1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2025-01-18 18:26:44 -06:00

Migrate workers and app widgets to coroutines (#907)

This commit is contained in:
Mikołaj Pich 2020-07-27 13:20:45 +02:00 committed by GitHub
parent 6c4f27aff5
commit 6a1a347579
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
73 changed files with 269 additions and 485 deletions

View File

@ -132,7 +132,6 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-rx2:1.3.8'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.8'
implementation "androidx.core:core-ktx:1.3.0"
@ -155,10 +154,9 @@ dependencies {
implementation "me.zhanghai.android.materialprogressbar:library:1.6.1"
implementation "androidx.work:work-runtime-ktx:$work_manager"
implementation "androidx.work:work-rxjava2:$work_manager"
implementation "androidx.work:work-gcm:$work_manager"
implementation 'com.github.PaulinaSadowska:RxWorkManagerObservers:1.0.0'
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
implementation "androidx.room:room-runtime:$room"
implementation "androidx.room:room-ktx:$room"
@ -174,9 +172,6 @@ dependencies {
implementation "com.ncapdevi:frag-nav:3.3.0"
implementation "com.github.YarikSOffice:lingver:1.2.2"
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
implementation "io.reactivex.rxjava2:rxjava:2.2.19"
implementation "com.google.code.gson:gson:2.8.6"
implementation "com.jakewharton.timber:timber:4.7.1"
implementation "at.favre.lib:slf4j-timber:1.0.1"

View File

@ -30,13 +30,6 @@
-dontwarn javax.annotation.**
#Config for ReactiveNetwork
-dontwarn com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
-dontwarn io.reactivex.functions.Function
-dontwarn rx.internal.util.**
-dontwarn sun.misc.Unsafe
#Config for MPAndroidChart
-keep class com.github.mikephil.charting.** { *; }

View File

@ -18,10 +18,7 @@ import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.CrashlyticsExceptionTree
import io.github.wulkanowy.utils.CrashlyticsTree
import io.github.wulkanowy.utils.DebugLogTree
import io.reactivex.exceptions.UndeliverableException
import io.reactivex.plugins.RxJavaPlugins
import timber.log.Timber
import java.io.IOException
import javax.inject.Inject
class WulkanowyApp : DaggerApplication(), Configuration.Provider {
@ -42,7 +39,6 @@ class WulkanowyApp : DaggerApplication(), Configuration.Provider {
override fun onCreate() {
super.onCreate()
RxJavaPlugins.setErrorHandler(::onError)
Lingver.init(this)
themeManager.applyDefaultTheme()
@ -66,14 +62,6 @@ class WulkanowyApp : DaggerApplication(), Configuration.Provider {
registerActivityLifecycleCallbacks(ActivityLifecycleLogger())
}
private fun onError(error: Throwable) {
//RxJava's too deep stack traces may cause SOE on older android devices
val cause = error.cause
if (error is UndeliverableException && cause is IOException || cause is InterruptedException || cause is StackOverflowError) {
Timber.e(cause, "An undeliverable error occurred")
} else throw error
}
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
return DaggerAppComponent.factory().create(this)
}

View File

@ -8,7 +8,6 @@ import dagger.Provides
import io.github.wulkanowy.WulkanowyApp
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.DispatchersProvider
import io.github.wulkanowy.utils.SchedulersProvider
import javax.inject.Singleton
@Module
@ -18,10 +17,6 @@ internal class AppModule {
@Provides
fun provideContext(app: WulkanowyApp): Context = app
@Singleton
@Provides
fun provideSchedulersProvider() = SchedulersProvider()
@Singleton
@Provides
fun provideDispatchersProvider() = DispatchersProvider()

View File

@ -12,14 +12,17 @@ import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import dagger.android.AndroidInjection
import io.github.wulkanowy.R
import io.github.wulkanowy.data.Status
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.services.sync.channels.UpcomingLessonsChannel.Companion.CHANNEL_ID
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.flowWithResource
import io.github.wulkanowy.utils.getCompatColor
import io.github.wulkanowy.utils.toLocalDateTime
import kotlinx.coroutines.rx2.rxSingle
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import timber.log.Timber
import javax.inject.Inject
@ -28,9 +31,6 @@ class TimetableNotificationReceiver : BroadcastReceiver() {
@Inject
lateinit var studentRepository: StudentRepository
@Inject
lateinit var schedulers: SchedulersProvider
companion object {
const val NOTIFICATION_TYPE_CURRENT = 1
const val NOTIFICATION_TYPE_UPCOMING = 2
@ -54,14 +54,14 @@ class TimetableNotificationReceiver : BroadcastReceiver() {
Timber.d("Receiving intent... ${intent.toUri(0)}")
AndroidInjection.inject(this, context)
rxSingle { studentRepository.getCurrentStudent(false) }
.subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread)
.subscribe({
val studentId = intent.getIntExtra(STUDENT_ID, 0)
if (it.studentId == studentId) prepareNotification(context, intent)
else Timber.d("Notification studentId($studentId) differs from current(${it.studentId})")
}, { Timber.e(it) })
flowWithResource {
val student = studentRepository.getCurrentStudent(false)
val studentId = intent.getIntExtra(STUDENT_ID, 0)
if (student.studentId == studentId) prepareNotification(context, intent)
else Timber.d("Notification studentId($studentId) differs from current(${student.studentId})")
}.onEach {
if (it.status == Status.ERROR) Timber.e(it.error!!)
}.launchIn(GlobalScope)
}
private fun prepareNotification(context: Context, intent: Intent) {

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy.services.sync
import android.os.Build.VERSION.SDK_INT
import android.os.Build.VERSION_CODES.O
import androidx.core.app.NotificationManagerCompat
import androidx.lifecycle.asFlow
import androidx.work.BackoffPolicy.EXPONENTIAL
import androidx.work.Constraints
import androidx.work.Data
@ -15,14 +16,13 @@ import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkInfo
import androidx.work.WorkManager
import com.paulinasadowska.rxworkmanagerobservers.extensions.getWorkInfoByIdObservable
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.db.SharedPrefProvider.Companion.APP_VERSION_CODE_KEY
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
import io.github.wulkanowy.services.sync.channels.Channel
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.isHolidays
import io.reactivex.Observable
import kotlinx.coroutines.flow.Flow
import timber.log.Timber
import java.time.LocalDate.now
import java.util.concurrent.TimeUnit.MINUTES
@ -67,7 +67,7 @@ class SyncManager @Inject constructor(
}
}
fun startOneTimeSyncWorker(): Observable<WorkInfo> {
fun startOneTimeSyncWorker(): Flow<WorkInfo> {
val work = OneTimeWorkRequestBuilder<SyncWorker>()
.setInputData(
Data.Builder()
@ -77,7 +77,8 @@ class SyncManager @Inject constructor(
.build()
workManager.enqueueUniqueWork("${SyncWorker::class.java.simpleName}_one_time", ExistingWorkPolicy.REPLACE, work)
return workManager.getWorkInfoByIdObservable(work.id)
return workManager.getWorkInfoByIdLiveData(work.id).asFlow()
}
fun stopSyncWorker() {

View File

@ -5,9 +5,9 @@ import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat.BigTextStyle
import androidx.core.app.NotificationCompat.PRIORITY_DEFAULT
import androidx.core.app.NotificationManagerCompat
import androidx.work.CoroutineWorker
import androidx.work.Data
import androidx.work.ListenableWorker
import androidx.work.RxWorker
import androidx.work.WorkerParameters
import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
@ -20,10 +20,7 @@ import io.github.wulkanowy.sdk.scrapper.exception.FeatureDisabledException
import io.github.wulkanowy.services.sync.channels.DebugChannel
import io.github.wulkanowy.services.sync.works.Work
import io.github.wulkanowy.utils.getCompatColor
import io.reactivex.Completable
import io.reactivex.Single
import kotlinx.coroutines.rx2.rxMaybe
import kotlinx.coroutines.rx2.rxSingle
import kotlinx.coroutines.coroutineScope
import timber.log.Timber
import kotlin.random.Random
@ -35,45 +32,43 @@ class SyncWorker @AssistedInject constructor(
private val works: Set<@JvmSuppressWildcards Work>,
private val preferencesRepository: PreferencesRepository,
private val notificationManager: NotificationManagerCompat
) : RxWorker(appContext, workerParameters) {
) : CoroutineWorker(appContext, workerParameters) {
override fun createWork(): Single<Result> {
override suspend fun doWork() = coroutineScope {
Timber.i("SyncWorker is starting")
return rxSingle { studentRepository.isCurrentStudentSet() }
.filter { true }
.flatMap { rxMaybe { studentRepository.getCurrentStudent() } }
.flatMapCompletable { student ->
rxSingle { semesterRepository.getCurrentSemester(student, true) }
.flatMapCompletable { semester ->
Completable.mergeDelayError(works.map { work ->
work.create(student, semester)
.onErrorResumeNext {
if (it is FeatureDisabledException || it is FeatureNotAvailableException) Completable.complete()
else Completable.error(it)
}
.doOnSubscribe { Timber.i("${work::class.java.simpleName} is starting") }
.doOnError { Timber.i("${work::class.java.simpleName} result: An exception occurred") }
.doOnComplete { Timber.i("${work::class.java.simpleName} result: Success") }
})
}
if (!studentRepository.isCurrentStudentSet()) return@coroutineScope Result.failure()
val student = studentRepository.getCurrentStudent()
val semester = semesterRepository.getCurrentSemester(student, true)
val exceptions = works.mapNotNull { work ->
try {
Timber.i("${work::class.java.simpleName} is starting")
work.doWork(student, semester)
Timber.i("${work::class.java.simpleName} result: Success")
null
} catch (e: Throwable) {
Timber.w("${work::class.java.simpleName} result: An exception ${e.message} occurred")
if (e is FeatureDisabledException || e is FeatureNotAvailableException) null
else e
}
.toSingleDefault(Result.success())
.onErrorReturn {
Timber.e(it, "There was an error during synchronization")
when {
inputData.getBoolean("one_time", false) -> {
Result.failure(Data.Builder()
.putString("error", it.toString())
.build()
)
}
else -> Result.retry()
}
}
.doOnSuccess {
if (preferencesRepository.isDebugNotificationEnable) notify(it)
Timber.i("SyncWorker result: $it")
}
val result = when {
exceptions.isNotEmpty() && inputData.getBoolean("one_time", false) -> {
Result.failure(Data.Builder()
.putString("error", exceptions.toString())
.build()
)
}
exceptions.isNotEmpty() -> Result.retry()
else -> Result.success()
}
if (preferencesRepository.isDebugNotificationEnable) notify(result)
Timber.i("SyncWorker result: $result")
result
}
private fun notify(result: Result) {

View File

@ -3,16 +3,14 @@ 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.attendancesummary.AttendanceSummaryRepository
import io.reactivex.Completable
import kotlinx.coroutines.rx2.rxCompletable
import io.github.wulkanowy.utils.waitForResult
import javax.inject.Inject
class AttendanceSummaryWork @Inject constructor(
private val attendanceSummaryRepository: AttendanceSummaryRepository
) : Work {
override fun create(student: Student, semester: Semester): Completable {
return rxCompletable { attendanceSummaryRepository.getAttendanceSummary(student, semester, -1, true).waitForResult() }
override suspend fun doWork(student: Student, semester: Semester) {
attendanceSummaryRepository.getAttendanceSummary(student, semester, -1, true).waitForResult()
}
}

View File

@ -5,14 +5,13 @@ import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.attendance.AttendanceRepository
import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.sunday
import io.reactivex.Completable
import kotlinx.coroutines.rx2.rxCompletable
import io.github.wulkanowy.utils.waitForResult
import java.time.LocalDate.now
import javax.inject.Inject
class AttendanceWork @Inject constructor(private val attendanceRepository: AttendanceRepository) : Work {
override fun create(student: Student, semester: Semester): Completable {
return rxCompletable { attendanceRepository.getAttendance(student, semester, now().monday, now().sunday, true).waitForResult() }
override suspend fun doWork(student: Student, semester: Semester) {
attendanceRepository.getAttendance(student, semester, now().monday, now().sunday, true).waitForResult()
}
}

View File

@ -5,8 +5,7 @@ import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.completedlessons.CompletedLessonsRepository
import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.sunday
import io.reactivex.Completable
import kotlinx.coroutines.rx2.rxCompletable
import io.github.wulkanowy.utils.waitForResult
import java.time.LocalDate.now
import javax.inject.Inject
@ -14,7 +13,7 @@ class CompletedLessonWork @Inject constructor(
private val completedLessonsRepository: CompletedLessonsRepository
) : Work {
override fun create(student: Student, semester: Semester): Completable {
return rxCompletable { completedLessonsRepository.getCompletedLessons(student, semester, now().monday, now().sunday, true).waitForResult() }
override suspend fun doWork(student: Student, semester: Semester) {
completedLessonsRepository.getCompletedLessons(student, semester, now().monday, now().sunday, true).waitForResult()
}
}

View File

@ -5,14 +5,13 @@ import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.exam.ExamRepository
import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.sunday
import io.reactivex.Completable
import kotlinx.coroutines.rx2.rxCompletable
import io.github.wulkanowy.utils.waitForResult
import java.time.LocalDate.now
import javax.inject.Inject
class ExamWork @Inject constructor(private val examRepository: ExamRepository) : Work {
override fun create(student: Student, semester: Semester): Completable {
return rxCompletable { examRepository.getExams(student, semester, now().monday, now().sunday, true).waitForResult() }
override suspend fun doWork(student: Student, semester: Semester) {
examRepository.getExams(student, semester, now().monday, now().sunday, true).waitForResult()
}
}

View File

@ -3,21 +3,18 @@ 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.gradestatistics.GradeStatisticsRepository
import io.reactivex.Completable
import kotlinx.coroutines.rx2.rxCompletable
import io.github.wulkanowy.utils.waitForResult
import javax.inject.Inject
class GradeStatisticsWork @Inject constructor(
private val gradeStatisticsRepository: GradeStatisticsRepository
) : Work {
override fun create(student: Student, semester: Semester): Completable {
return rxCompletable {
with(gradeStatisticsRepository) {
getGradesStatistics(student, semester, "Wszystkie", isSemester = true, forceRefresh = true).waitForResult()
getGradesStatistics(student, semester, "Wszystkie", isSemester = false, forceRefresh = true).waitForResult()
getGradesPointsStatistics(student, semester, "Wszystkie", forceRefresh = true).waitForResult()
}
override suspend fun doWork(student: Student, semester: Semester) {
with(gradeStatisticsRepository) {
getGradesStatistics(student, semester, "Wszystkie", isSemester = true, forceRefresh = true).waitForResult()
getGradesStatistics(student, semester, "Wszystkie", isSemester = false, forceRefresh = true).waitForResult()
getGradesPointsStatistics(student, semester, "Wszystkie", forceRefresh = true).waitForResult()
}
}
}

View File

@ -18,10 +18,8 @@ import io.github.wulkanowy.services.sync.channels.NewGradesChannel
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.getCompatColor
import io.reactivex.Completable
import io.github.wulkanowy.utils.waitForResult
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.rx2.rxCompletable
import kotlinx.coroutines.rx2.rxSingle
import javax.inject.Inject
import kotlin.random.Random
@ -32,18 +30,23 @@ class GradeWork @Inject constructor(
private val preferencesRepository: PreferencesRepository
) : Work {
override fun create(student: Student, semester: Semester): Completable {
return rxCompletable { gradeRepository.getGrades(student, semester, true, preferencesRepository.isNotificationsEnable).waitForResult() }
.concatWith(Completable.concatArray(rxSingle { gradeRepository.getNotNotifiedGrades(semester).first() }.flatMapCompletable {
if (it.isNotEmpty()) notifyDetails(it)
rxCompletable { gradeRepository.updateGrades(it.onEach { grade -> grade.isNotified = true }) }
}, rxSingle { gradeRepository.getNotNotifiedPredictedGrades(semester).first() }.flatMapCompletable {
if (it.isNotEmpty()) notifyPredicted(it)
rxCompletable { gradeRepository.updateGradesSummary(it.onEach { grade -> grade.isPredictedGradeNotified = true }) }
}, rxSingle { gradeRepository.getNotNotifiedFinalGrades(semester).first() }.flatMapCompletable {
if (it.isNotEmpty()) notifyFinal(it)
rxCompletable { gradeRepository.updateGradesSummary(it.onEach { grade -> grade.isFinalGradeNotified = true }) }
}))
override suspend fun doWork(student: Student, semester: Semester) {
gradeRepository.getGrades(student, semester, true, preferencesRepository.isNotificationsEnable).waitForResult()
gradeRepository.getNotNotifiedGrades(semester).first().let {
if (it.isNotEmpty()) notifyDetails(it)
gradeRepository.updateGrades(it.onEach { grade -> grade.isNotified = true })
}
gradeRepository.getNotNotifiedPredictedGrades(semester).first().let {
if (it.isNotEmpty()) notifyPredicted(it)
gradeRepository.updateGradesSummary(it.onEach { grade -> grade.isPredictedGradeNotified = true })
}
gradeRepository.getNotNotifiedFinalGrades(semester).first().let {
if (it.isNotEmpty()) notifyFinal(it)
gradeRepository.updateGradesSummary(it.onEach { grade -> grade.isFinalGradeNotified = true })
}
}
private fun getNotificationBuilder(): NotificationCompat.Builder {

View File

@ -5,14 +5,13 @@ import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.homework.HomeworkRepository
import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.sunday
import io.reactivex.Completable
import kotlinx.coroutines.rx2.rxCompletable
import io.github.wulkanowy.utils.waitForResult
import java.time.LocalDate.now
import javax.inject.Inject
class HomeworkWork @Inject constructor(private val homeworkRepository: HomeworkRepository) : Work {
override fun create(student: Student, semester: Semester): Completable {
return rxCompletable { homeworkRepository.getHomework(student, semester, now().monday, now().sunday, true).waitForResult() }
override suspend fun doWork(student: Student, semester: Semester) {
homeworkRepository.getHomework(student, semester, now().monday, now().sunday, true).waitForResult()
}
}

View File

@ -17,10 +17,8 @@ import io.github.wulkanowy.services.sync.channels.LuckyNumberChannel
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.getCompatColor
import io.reactivex.Completable
import io.github.wulkanowy.utils.waitForResult
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.rx2.rxCompletable
import kotlinx.coroutines.rx2.rxMaybe
import javax.inject.Inject
import kotlin.random.Random
@ -31,13 +29,13 @@ class LuckyNumberWork @Inject constructor(
private val preferencesRepository: PreferencesRepository
) : Work {
override fun create(student: Student, semester: Semester): Completable {
return rxMaybe { luckyNumberRepository.getLuckyNumber(student, true, preferencesRepository.isNotificationsEnable).waitForResult() }
.flatMap { rxMaybe { luckyNumberRepository.getNotNotifiedLuckyNumber(student).first() } }
.flatMapCompletable {
notify(it)
rxCompletable { luckyNumberRepository.updateLuckyNumber(it.apply { isNotified = true }) }
}
override suspend fun doWork(student: Student, semester: Semester) {
luckyNumberRepository.getLuckyNumber(student, true, preferencesRepository.isNotificationsEnable).waitForResult()
luckyNumberRepository.getNotNotifiedLuckyNumber(student).first()?.let {
notify(it)
luckyNumberRepository.updateLuckyNumber(it.apply { isNotified = true })
}
}
private fun notify(luckyNumber: LuckyNumber) {

View File

@ -18,10 +18,8 @@ import io.github.wulkanowy.services.sync.channels.NewMessagesChannel
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.getCompatColor
import io.reactivex.Completable
import io.github.wulkanowy.utils.waitForResult
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.rx2.rxCompletable
import kotlinx.coroutines.rx2.rxSingle
import javax.inject.Inject
import kotlin.random.Random
@ -32,13 +30,13 @@ class MessageWork @Inject constructor(
private val preferencesRepository: PreferencesRepository
) : Work {
override fun create(student: Student, semester: Semester): Completable {
return rxSingle { messageRepository.getMessages(student, semester, RECEIVED, true, preferencesRepository.isNotificationsEnable).waitForResult() }
.flatMap { rxSingle { messageRepository.getNotNotifiedMessages(student).first() } }
.flatMapCompletable {
if (it.isNotEmpty()) notify(it)
rxCompletable { messageRepository.updateMessages(it.onEach { message -> message.isNotified = true }) }
}
override suspend fun doWork(student: Student, semester: Semester) {
messageRepository.getMessages(student, semester, RECEIVED, true, preferencesRepository.isNotificationsEnable).waitForResult()
messageRepository.getNotNotifiedMessages(student).first().let {
if (it.isNotEmpty()) notify(it)
messageRepository.updateMessages(it.onEach { message -> message.isNotified = true })
}
}
private fun notify(messages: List<Message>) {

View File

@ -17,10 +17,8 @@ import io.github.wulkanowy.services.sync.channels.NewNotesChannel
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.getCompatColor
import io.reactivex.Completable
import io.github.wulkanowy.utils.waitForResult
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.rx2.rxCompletable
import kotlinx.coroutines.rx2.rxSingle
import javax.inject.Inject
import kotlin.random.Random
@ -31,13 +29,13 @@ class NoteWork @Inject constructor(
private val preferencesRepository: PreferencesRepository
) : Work {
override fun create(student: Student, semester: Semester): Completable {
return rxSingle { noteRepository.getNotes(student, semester, true, preferencesRepository.isNotificationsEnable).waitForResult() }
.flatMap { rxSingle { noteRepository.getNotNotifiedNotes(student).first() } }
.flatMapCompletable {
if (it.isNotEmpty()) notify(it)
rxCompletable { noteRepository.updateNotes(it.onEach { note -> note.isNotified = true }) }
}
override suspend fun doWork(student: Student, semester: Semester) {
noteRepository.getNotes(student, semester, true, preferencesRepository.isNotificationsEnable).waitForResult()
noteRepository.getNotNotifiedNotes(student).first().let {
if (it.isNotEmpty()) notify(it)
noteRepository.updateNotes(it.onEach { note -> note.isNotified = true })
}
}
private fun notify(notes: List<Note>) {

View File

@ -4,9 +4,6 @@ import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.recipient.RecipientRepository
import io.github.wulkanowy.data.repositories.reportingunit.ReportingUnitRepository
import io.reactivex.Completable
import kotlinx.coroutines.rx2.rxCompletable
import kotlinx.coroutines.rx2.rxSingle
import javax.inject.Inject
class RecipientWork @Inject constructor(
@ -14,14 +11,13 @@ class RecipientWork @Inject constructor(
private val recipientRepository: RecipientRepository
) : Work {
override fun create(student: Student, semester: Semester): Completable {
return rxSingle { reportingUnitRepository.refreshReportingUnits(student) }
.flatMap { rxSingle { reportingUnitRepository.getReportingUnits(student) } }
.flatMapCompletable { units ->
Completable.mergeDelayError(units.map {
rxCompletable { recipientRepository.refreshRecipients(student, 2, it) }
})
override suspend fun doWork(student: Student, semester: Semester) {
reportingUnitRepository.refreshReportingUnits(student)
reportingUnitRepository.getReportingUnits(student).let { units ->
units.map {
recipientRepository.refreshRecipients(student, 2, it)
}
}
}
}

View File

@ -3,13 +3,12 @@ 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.teacher.TeacherRepository
import io.reactivex.Completable
import kotlinx.coroutines.rx2.rxCompletable
import io.github.wulkanowy.utils.waitForResult
import javax.inject.Inject
class TeacherWork @Inject constructor(private val teacherRepository: TeacherRepository) : Work {
override fun create(student: Student, semester: Semester): Completable {
return rxCompletable { teacherRepository.getTeachers(student, semester, true).waitForResult() }
override suspend fun doWork(student: Student, semester: Semester) {
teacherRepository.getTeachers(student, semester, true).waitForResult()
}
}

View File

@ -5,14 +5,15 @@ import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.timetable.TimetableRepository
import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.sunday
import io.reactivex.Completable
import kotlinx.coroutines.rx2.rxCompletable
import io.github.wulkanowy.utils.waitForResult
import java.time.LocalDate.now
import javax.inject.Inject
class TimetableWork @Inject constructor(private val timetableRepository: TimetableRepository) : Work {
class TimetableWork @Inject constructor(
private val timetableRepository: TimetableRepository
) : Work {
override fun create(student: Student, semester: Semester): Completable {
return rxCompletable { timetableRepository.getTimetable(student, semester, now().monday, now().sunday, true).waitForResult() }
override suspend fun doWork(student: Student, semester: Semester) {
timetableRepository.getTimetable(student, semester, now().monday, now().sunday, true).waitForResult()
}
}

View File

@ -1,19 +1,9 @@
package io.github.wulkanowy.services.sync.works
import io.github.wulkanowy.data.Resource
import io.github.wulkanowy.data.Status
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.reactivex.Completable
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.takeWhile
interface Work {
fun create(student: Student, semester: Semester): Completable
suspend fun <T> Flow<Resource<T>>.waitForResult() = takeWhile {
it.status == Status.LOADING
}.collect()
suspend fun doWork(student: Student, semester: Semester)
}

View File

@ -9,7 +9,7 @@ import io.github.wulkanowy.data.repositories.semester.SemesterRepository
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.data.repositories.timetable.TimetableRepository
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetFactory
import io.github.wulkanowy.utils.SchedulersProvider
import timber.log.Timber
import javax.inject.Inject
class TimetableWidgetService : RemoteViewsService() {
@ -29,11 +29,9 @@ class TimetableWidgetService : RemoteViewsService() {
@Inject
lateinit var sharedPref: SharedPrefProvider
@Inject
lateinit var schedulers: SchedulersProvider
override fun onGetViewFactory(intent: Intent?): RemoteViewsFactory {
AndroidInjection.inject(this)
return TimetableWidgetFactory(timetableRepo, studentRepo, semesterRepo, prefRepository, sharedPref, schedulers, applicationContext, intent)
Timber.d("TimetableWidgetFactory created")
return TimetableWidgetFactory(timetableRepo, studentRepo, semesterRepo, prefRepository, sharedPref, applicationContext, intent)
}
}

View File

@ -2,9 +2,7 @@ package io.github.wulkanowy.ui.base
import io.github.wulkanowy.data.Status
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.flowWithResource
import io.reactivex.disposables.CompositeDisposable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@ -16,8 +14,7 @@ import kotlin.coroutines.CoroutineContext
open class BasePresenter<T : BaseView>(
protected val errorHandler: ErrorHandler,
protected val studentRepository: StudentRepository,
protected val schedulers: SchedulersProvider
protected val studentRepository: StudentRepository
) : CoroutineScope {
private var job: Job = Job()
@ -27,9 +24,6 @@ open class BasePresenter<T : BaseView>(
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job
@Deprecated("Use flow instead :)")
val disposable = CompositeDisposable()
var view: T? = null
open fun onAttachView(view: T) {
@ -83,7 +77,6 @@ open class BasePresenter<T : BaseView>(
open fun onDetachView() {
view = null
disposable.clear()
job.cancel()
errorHandler.clear()
}

View File

@ -5,17 +5,15 @@ 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.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import timber.log.Timber
import javax.inject.Inject
class AboutPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val appInfo: AppInfo,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<AboutView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<AboutView>(errorHandler, studentRepository) {
override fun onAttachView(view: AboutView) {
super.onAttachView(view)

View File

@ -6,17 +6,15 @@ import io.github.wulkanowy.data.repositories.appcreator.AppCreatorRepository
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.flowWithResource
import kotlinx.coroutines.flow.onEach
import javax.inject.Inject
class ContributorPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val appCreatorRepository: AppCreatorRepository
) : BasePresenter<ContributorView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<ContributorView>(errorHandler, studentRepository) {
override fun onAttachView(view: ContributorView) {
super.onAttachView(view)

View File

@ -6,7 +6,6 @@ import io.github.wulkanowy.data.repositories.student.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.SchedulersProvider
import io.github.wulkanowy.utils.afterLoading
import io.github.wulkanowy.utils.flowWithResource
import kotlinx.coroutines.flow.onEach
@ -15,11 +14,10 @@ import timber.log.Timber
import javax.inject.Inject
class LicensePresenter @Inject constructor(
schedulers: SchedulersProvider,
private val dispatchers: DispatchersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository
) : BasePresenter<LicenseView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<LicenseView>(errorHandler, studentRepository) {
override fun onAttachView(view: LicenseView) {
super.onAttachView(view)

View File

@ -5,18 +5,16 @@ import io.github.wulkanowy.data.repositories.logger.LoggerRepository
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.flowWithResource
import kotlinx.coroutines.flow.onEach
import timber.log.Timber
import javax.inject.Inject
class LogViewerPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val loggerRepository: LoggerRepository
) : BasePresenter<LogViewerView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<LogViewerView>(errorHandler, studentRepository) {
override fun onAttachView(view: LogViewerView) {
super.onAttachView(view)

View File

@ -6,7 +6,6 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
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.utils.SchedulersProvider
import io.github.wulkanowy.utils.afterLoading
import io.github.wulkanowy.utils.flowWithResource
import kotlinx.coroutines.flow.onEach
@ -14,11 +13,10 @@ import timber.log.Timber
import javax.inject.Inject
class AccountPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val syncManager: SyncManager
) : BasePresenter<AccountView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<AccountView>(errorHandler, studentRepository) {
override fun onAttachView(view: AccountView) {
super.onAttachView(view)

View File

@ -10,7 +10,6 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
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.afterLoading
import io.github.wulkanowy.utils.flowWithResource
import io.github.wulkanowy.utils.flowWithResourceIn
@ -30,14 +29,13 @@ import java.time.LocalDate.ofEpochDay
import javax.inject.Inject
class AttendancePresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val attendanceRepository: AttendanceRepository,
private val semesterRepository: SemesterRepository,
private val prefRepository: PreferencesRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<AttendanceView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<AttendanceView>(errorHandler, studentRepository) {
private var baseDate: LocalDate = now().previousOrSameSchoolDay

View File

@ -9,7 +9,6 @@ import io.github.wulkanowy.data.repositories.subject.SubjectRepository
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.afterLoading
import io.github.wulkanowy.utils.flowWithResourceIn
import kotlinx.coroutines.flow.onEach
@ -18,14 +17,13 @@ import java.time.Month
import javax.inject.Inject
class AttendanceSummaryPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val attendanceSummaryRepository: AttendanceSummaryRepository,
private val subjectRepository: SubjectRepository,
private val semesterRepository: SemesterRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<AttendanceSummaryView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<AttendanceSummaryView>(errorHandler, studentRepository) {
private var subjects = emptyList<Subject>()

View File

@ -8,7 +8,6 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
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.afterLoading
import io.github.wulkanowy.utils.flowWithResourceIn
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
@ -27,13 +26,12 @@ import java.time.LocalDate.ofEpochDay
import javax.inject.Inject
class ExamPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val examRepository: ExamRepository,
private val semesterRepository: SemesterRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<ExamView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<ExamView>(errorHandler, studentRepository) {
private var baseDate: LocalDate = now().nextOrSameSchoolDay

View File

@ -7,7 +7,6 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
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.flowWithResource
import io.github.wulkanowy.utils.getCurrentOrLast
import kotlinx.coroutines.delay
@ -16,12 +15,11 @@ import timber.log.Timber
import javax.inject.Inject
class GradePresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val semesterRepository: SemesterRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<GradeView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<GradeView>(errorHandler, studentRepository) {
var selectedIndex = 0
private set

View File

@ -11,7 +11,6 @@ import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider
import io.github.wulkanowy.ui.modules.grade.GradeDetailsWithAverage
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.afterLoading
import io.github.wulkanowy.utils.flowWithResource
import io.github.wulkanowy.utils.flowWithResourceIn
@ -21,7 +20,6 @@ import timber.log.Timber
import javax.inject.Inject
class GradeDetailsPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val gradeRepository: GradeRepository,
@ -29,7 +27,7 @@ class GradeDetailsPresenter @Inject constructor(
private val preferencesRepository: PreferencesRepository,
private val averageProvider: GradeAverageProvider,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<GradeDetailsView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<GradeDetailsView>(errorHandler, studentRepository) {
private var newGradesAmount: Int = 0

View File

@ -10,7 +10,6 @@ import io.github.wulkanowy.data.repositories.subject.SubjectRepository
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.afterLoading
import io.github.wulkanowy.utils.flowWithResourceIn
import kotlinx.coroutines.flow.onEach
@ -18,7 +17,6 @@ import timber.log.Timber
import javax.inject.Inject
class GradeStatisticsPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val gradeStatisticsRepository: GradeStatisticsRepository,
@ -26,7 +24,7 @@ class GradeStatisticsPresenter @Inject constructor(
private val semesterRepository: SemesterRepository,
private val preferencesRepository: PreferencesRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<GradeStatisticsView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<GradeStatisticsView>(errorHandler, studentRepository) {
private var subjects = emptyList<Subject>()

View File

@ -8,7 +8,6 @@ import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider
import io.github.wulkanowy.ui.modules.grade.GradeDetailsWithAverage
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.afterLoading
import io.github.wulkanowy.utils.flowWithResourceIn
import kotlinx.coroutines.flow.onEach
@ -16,12 +15,11 @@ import timber.log.Timber
import javax.inject.Inject
class GradeSummaryPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val averageProvider: GradeAverageProvider,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<GradeSummaryView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<GradeSummaryView>(errorHandler, studentRepository) {
private lateinit var lastError: Throwable

View File

@ -8,7 +8,6 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
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.afterLoading
import io.github.wulkanowy.utils.flowWithResourceIn
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
@ -26,13 +25,12 @@ import java.time.LocalDate.ofEpochDay
import javax.inject.Inject
class HomeworkPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val homeworkRepository: HomeworkRepository,
private val semesterRepository: SemesterRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<HomeworkView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<HomeworkView>(errorHandler, studentRepository) {
private var baseDate: LocalDate = LocalDate.now().nextOrSameSchoolDay

View File

@ -7,19 +7,17 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
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.flowWithResource
import kotlinx.coroutines.flow.onEach
import timber.log.Timber
import javax.inject.Inject
class HomeworkDetailsPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val homeworkRepository: HomeworkRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<HomeworkDetailsView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<HomeworkDetailsView>(errorHandler, studentRepository) {
override fun onAttachView(view: HomeworkDetailsView) {
super.onAttachView(view)

View File

@ -4,15 +4,13 @@ import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.SchedulersProvider
import timber.log.Timber
import javax.inject.Inject
class LoginPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository
) : BasePresenter<LoginView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<LoginView>(errorHandler, studentRepository) {
override fun onAttachView(view: LoginView) {
super.onAttachView(view)

View File

@ -7,7 +7,6 @@ import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.afterLoading
import io.github.wulkanowy.utils.flowWithResource
import io.github.wulkanowy.utils.ifNullOrBlank
@ -16,11 +15,10 @@ import timber.log.Timber
import javax.inject.Inject
class LoginAdvancedPresenter @Inject constructor(
schedulers: SchedulersProvider,
studentRepository: StudentRepository,
private val loginErrorHandler: LoginErrorHandler,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<LoginAdvancedView>(loginErrorHandler, studentRepository, schedulers) {
) : BasePresenter<LoginAdvancedView>(loginErrorHandler, studentRepository) {
override fun onAttachView(view: LoginAdvancedView) {
super.onAttachView(view)

View File

@ -5,7 +5,6 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.afterLoading
import io.github.wulkanowy.utils.flowWithResource
import io.github.wulkanowy.utils.ifNullOrBlank
@ -14,11 +13,10 @@ import timber.log.Timber
import javax.inject.Inject
class LoginFormPresenter @Inject constructor(
schedulers: SchedulersProvider,
studentRepository: StudentRepository,
private val loginErrorHandler: LoginErrorHandler,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<LoginFormView>(loginErrorHandler, studentRepository, schedulers) {
) : BasePresenter<LoginFormView>(loginErrorHandler, studentRepository) {
private var lastError: Throwable? = null

View File

@ -5,7 +5,6 @@ import io.github.wulkanowy.data.repositories.recover.RecoverRepository
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.afterLoading
import io.github.wulkanowy.utils.flowWithResource
import io.github.wulkanowy.utils.ifNullOrBlank
@ -14,12 +13,11 @@ import timber.log.Timber
import javax.inject.Inject
class LoginRecoverPresenter @Inject constructor(
schedulers: SchedulersProvider,
studentRepository: StudentRepository,
private val loginErrorHandler: RecoverErrorHandler,
private val analytics: FirebaseAnalyticsHelper,
private val recoverRepository: RecoverRepository
) : BasePresenter<LoginRecoverView>(loginErrorHandler, studentRepository, schedulers) {
) : BasePresenter<LoginRecoverView>(loginErrorHandler, studentRepository) {
private lateinit var lastError: Throwable

View File

@ -6,7 +6,6 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.flowWithResource
import io.github.wulkanowy.utils.ifNullOrBlank
import kotlinx.coroutines.flow.onEach
@ -15,11 +14,10 @@ import java.io.Serializable
import javax.inject.Inject
class LoginStudentSelectPresenter @Inject constructor(
schedulers: SchedulersProvider,
studentRepository: StudentRepository,
private val loginErrorHandler: LoginErrorHandler,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<LoginStudentSelectView>(loginErrorHandler, studentRepository, schedulers) {
) : BasePresenter<LoginStudentSelectView>(loginErrorHandler, studentRepository) {
private var lastError: Throwable? = null

View File

@ -5,7 +5,6 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.afterLoading
import io.github.wulkanowy.utils.flowWithResource
import io.github.wulkanowy.utils.ifNullOrBlank
@ -16,10 +15,9 @@ import javax.inject.Inject
class LoginSymbolPresenter @Inject constructor(
studentRepository: StudentRepository,
schedulers: SchedulersProvider,
private val loginErrorHandler: LoginErrorHandler,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<LoginSymbolView>(loginErrorHandler, studentRepository, schedulers) {
) : BasePresenter<LoginSymbolView>(loginErrorHandler, studentRepository) {
private var lastError: Throwable? = null

View File

@ -6,7 +6,6 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
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.afterLoading
import io.github.wulkanowy.utils.flowWithResourceIn
import kotlinx.coroutines.flow.onEach
@ -14,12 +13,11 @@ import timber.log.Timber
import javax.inject.Inject
class LuckyNumberPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val luckyNumberRepository: LuckyNumberRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<LuckyNumberView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<LuckyNumberView>(errorHandler, studentRepository) {
private lateinit var lastError: Throwable

View File

@ -8,18 +8,16 @@ 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.SchedulersProvider
import io.github.wulkanowy.utils.flowWithResource
import kotlinx.coroutines.flow.onEach
import timber.log.Timber
import javax.inject.Inject
class LuckyNumberWidgetConfigurePresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val sharedPref: SharedPrefProvider
) : BasePresenter<LuckyNumberWidgetConfigureView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<LuckyNumberWidgetConfigureView>(errorHandler, studentRepository) {
private var appWidgetId: Int? = null

View File

@ -15,20 +15,14 @@ import android.view.View.VISIBLE
import android.widget.RemoteViews
import dagger.android.AndroidInjection
import io.github.wulkanowy.R
import io.github.wulkanowy.data.Status
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.luckynumber.LuckyNumberRepository
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.SchedulersProvider
import io.reactivex.Maybe
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.takeWhile
import kotlinx.coroutines.rx2.rxMaybe
import kotlinx.coroutines.rx2.rxSingle
import io.github.wulkanowy.utils.toFirstResult
import kotlinx.coroutines.runBlocking
import timber.log.Timber
import javax.inject.Inject
@ -40,12 +34,6 @@ class LuckyNumberWidgetProvider : AppWidgetProvider() {
@Inject
lateinit var luckyNumberRepository: LuckyNumberRepository
@Inject
lateinit var schedulers: SchedulersProvider
@Inject
lateinit var appWidgetManager: AppWidgetManager
@Inject
lateinit var sharedPref: SharedPrefProvider
@ -142,27 +130,23 @@ class LuckyNumberWidgetProvider : AppWidgetProvider() {
return n - 1
}
private fun getLuckyNumber(studentId: Long, appWidgetId: Int): LuckyNumber? {
return try {
rxSingle { studentRepository.isStudentSaved() }
.filter { true }
.flatMap { rxMaybe { studentRepository.getSavedStudents() } }
.flatMap { students ->
val student = students.singleOrNull { student -> student.id == studentId }
when {
student != null -> Maybe.just(student)
studentId != 0L -> {
rxSingle { studentRepository.isCurrentStudentSet() }
.filter { true }
.flatMap { rxMaybe { studentRepository.getCurrentStudent(false) } }
.doOnSuccess { sharedPref.putLong(getStudentWidgetKey(appWidgetId), it.id) }
}
else -> Maybe.empty()
private fun getLuckyNumber(studentId: Long, appWidgetId: Int) = runBlocking {
try {
val students = studentRepository.getSavedStudents()
val student = students.singleOrNull { student -> student.id == studentId }
val currentStudent = when {
student != null -> student
studentId != 0L && studentRepository.isCurrentStudentSet() -> {
studentRepository.getCurrentStudent(false).also {
sharedPref.putLong(getStudentWidgetKey(appWidgetId), it.id)
}
}
.flatMap { rxMaybe { luckyNumberRepository.getLuckyNumber(it, false).takeWhile { it.status == Status.LOADING }.first().data } }
.subscribeOn(schedulers.backgroundThread)
.blockingGet()
else -> null
}
currentStudent?.let {
luckyNumberRepository.getLuckyNumber(it, false).toFirstResult().data
}
} catch (e: Exception) {
if (e.cause !is NoCurrentStudentException) {
Timber.e(e, "An error has occurred in lucky number provider")

View File

@ -9,18 +9,16 @@ import io.github.wulkanowy.ui.modules.main.MainView.Section.GRADE
import io.github.wulkanowy.ui.modules.main.MainView.Section.MESSAGE
import io.github.wulkanowy.ui.modules.main.MainView.Section.SCHOOL
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import timber.log.Timber
import javax.inject.Inject
class MainPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val prefRepository: PreferencesRepository,
private val syncManager: SyncManager,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<MainView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<MainView>(errorHandler, studentRepository) {
fun onAttachView(view: MainView, initMenu: MainView.Section?) {
super.onAttachView(view)

View File

@ -3,17 +3,15 @@ package io.github.wulkanowy.ui.modules.message
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.SchedulersProvider
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
class MessagePresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository
) : BasePresenter<MessageView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<MessageView>(errorHandler, studentRepository) {
override fun onAttachView(view: MessageView) {
super.onAttachView(view)

View File

@ -11,7 +11,6 @@ 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.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.afterLoading
import io.github.wulkanowy.utils.flowWithResource
import io.github.wulkanowy.utils.flowWithResourceIn
@ -21,13 +20,12 @@ import timber.log.Timber
import javax.inject.Inject
class MessagePreviewPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val messageRepository: MessageRepository,
private val analytics: FirebaseAnalyticsHelper,
private var appInfo: AppInfo
) : BasePresenter<MessagePreviewView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<MessagePreviewView>(errorHandler, studentRepository) {
var message: Message? = null

View File

@ -12,7 +12,6 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
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.afterLoading
import io.github.wulkanowy.utils.flowWithResource
import io.github.wulkanowy.utils.toFormattedString
@ -21,7 +20,6 @@ import timber.log.Timber
import javax.inject.Inject
class SendMessagePresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val semesterRepository: SemesterRepository,
@ -30,7 +28,7 @@ class SendMessagePresenter @Inject constructor(
private val recipientRepository: RecipientRepository,
private val preferencesRepository: PreferencesRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<SendMessageView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<SendMessageView>(errorHandler, studentRepository) {
fun onAttachView(view: SendMessageView, message: Message?, reply: Boolean?) {
super.onAttachView(view)

View File

@ -9,7 +9,6 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
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.afterLoading
import io.github.wulkanowy.utils.flowWithResourceIn
import io.github.wulkanowy.utils.toFormattedString
@ -28,13 +27,12 @@ import javax.inject.Inject
import kotlin.math.pow
class MessageTabPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val messageRepository: MessageRepository,
private val semesterRepository: SemesterRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<MessageTabView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<MessageTabView>(errorHandler, studentRepository) {
lateinit var folder: MessageFolder

View File

@ -8,7 +8,6 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
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.afterLoading
import io.github.wulkanowy.utils.flowWithResource
import io.github.wulkanowy.utils.flowWithResourceIn
@ -18,13 +17,12 @@ import timber.log.Timber
import javax.inject.Inject
class MobileDevicePresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val semesterRepository: SemesterRepository,
private val mobileDeviceRepository: MobileDeviceRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<MobileDeviceView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<MobileDeviceView>(errorHandler, studentRepository) {
private lateinit var lastError: Throwable

View File

@ -7,7 +7,6 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
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.afterLoading
import io.github.wulkanowy.utils.flowWithResource
import kotlinx.coroutines.flow.onEach
@ -15,13 +14,12 @@ import timber.log.Timber
import javax.inject.Inject
class MobileDeviceTokenPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val semesterRepository: SemesterRepository,
private val mobileDeviceRepository: MobileDeviceRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<MobileDeviceTokenVIew>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<MobileDeviceTokenVIew>(errorHandler, studentRepository) {
override fun onAttachView(view: MobileDeviceTokenVIew) {
super.onAttachView(view)

View File

@ -3,15 +3,13 @@ package io.github.wulkanowy.ui.modules.more
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.SchedulersProvider
import timber.log.Timber
import javax.inject.Inject
class MorePresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository
) : BasePresenter<MoreView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<MoreView>(errorHandler, studentRepository) {
override fun onAttachView(view: MoreView) {
super.onAttachView(view)

View File

@ -8,7 +8,6 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
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.afterLoading
import io.github.wulkanowy.utils.flowWithResource
import io.github.wulkanowy.utils.flowWithResourceIn
@ -18,13 +17,12 @@ import timber.log.Timber
import javax.inject.Inject
class NotePresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val noteRepository: NoteRepository,
private val semesterRepository: SemesterRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<NoteView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<NoteView>(errorHandler, studentRepository) {
private lateinit var lastError: Throwable

View File

@ -3,17 +3,15 @@ package io.github.wulkanowy.ui.modules.schoolandteachers
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.SchedulersProvider
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
class SchoolAndTeachersPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository
) : BasePresenter<SchoolAndTeachersView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<SchoolAndTeachersView>(errorHandler, studentRepository) {
override fun onAttachView(view: SchoolAndTeachersView) {
super.onAttachView(view)

View File

@ -7,7 +7,6 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
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.afterLoading
import io.github.wulkanowy.utils.flowWithResourceIn
import kotlinx.coroutines.flow.onEach
@ -15,13 +14,12 @@ import timber.log.Timber
import javax.inject.Inject
class SchoolPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val semesterRepository: SemesterRepository,
private val schoolRepository: SchoolRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<SchoolView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<SchoolView>(errorHandler, studentRepository) {
private var address: String? = null

View File

@ -7,7 +7,6 @@ import io.github.wulkanowy.data.repositories.teacher.TeacherRepository
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.afterLoading
import io.github.wulkanowy.utils.flowWithResourceIn
import kotlinx.coroutines.flow.onEach
@ -15,13 +14,12 @@ import timber.log.Timber
import javax.inject.Inject
class TeacherPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val semesterRepository: SemesterRepository,
private val teacherRepository: TeacherRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<TeacherView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<TeacherView>(errorHandler, studentRepository) {
private lateinit var lastError: Throwable

View File

@ -10,14 +10,14 @@ 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.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.isHolidays
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.onEach
import timber.log.Timber
import java.time.LocalDate.now
import javax.inject.Inject
class SettingsPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val preferencesRepository: PreferencesRepository,
@ -26,7 +26,7 @@ class SettingsPresenter @Inject constructor(
private val syncManager: SyncManager,
private val chuckerCollector: ChuckerCollector,
private val appInfo: AppInfo
) : BasePresenter<SettingsView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<SettingsView>(errorHandler, studentRepository) {
override fun onAttachView(view: SettingsView) {
super.onAttachView(view)
@ -64,31 +64,27 @@ class SettingsPresenter @Inject constructor(
fun onForceSyncDialogSubmit() {
view?.run {
val successString = syncSuccessString
val failedString = syncFailedString
disposable.add(syncManager.startOneTimeSyncWorker()
.doOnSubscribe {
setSyncInProgress(true)
Timber.i("Setting sync now started")
analytics.logEvent("sync_now", "status" to "started")
}
.doFinally { setSyncInProgress(false) }
.subscribe({ workInfo ->
when (workInfo.state) {
WorkInfo.State.SUCCEEDED -> {
showMessage(successString)
analytics.logEvent("sync_now", "status" to "success")
}
WorkInfo.State.FAILED -> {
showError(failedString, Throwable(workInfo.outputData.getString("error")))
analytics.logEvent("sync_now", "status" to "failed")
}
else -> Timber.d("Sync now state: ${workInfo.state}")
syncManager.startOneTimeSyncWorker().onEach { workInfo ->
when (workInfo.state) {
WorkInfo.State.ENQUEUED -> {
setSyncInProgress(true)
Timber.i("Setting sync now started")
analytics.logEvent("sync_now", "status" to "started")
}
}, {
Timber.e(it, "Sync now failed")
})
)
WorkInfo.State.SUCCEEDED -> {
showMessage(syncSuccessString)
analytics.logEvent("sync_now", "status" to "success")
}
WorkInfo.State.FAILED -> {
showError(syncFailedString, Throwable(workInfo.outputData.getString("error")))
analytics.logEvent("sync_now", "status" to "failed")
}
else -> Timber.d("Sync now state: ${workInfo.state}")
}
if (workInfo.state.isFinished) setSyncInProgress(false)
}.catch {
Timber.e(it, "Sync now failed")
}.launch("sync")
}
}
}

View File

@ -4,17 +4,15 @@ import io.github.wulkanowy.data.Status
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.flowWithResource
import kotlinx.coroutines.flow.onEach
import timber.log.Timber
import javax.inject.Inject
class SplashPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository
) : BasePresenter<SplashView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<SplashView>(errorHandler, studentRepository) {
override fun onAttachView(view: SplashView) {
super.onAttachView(view)

View File

@ -10,7 +10,6 @@ import io.github.wulkanowy.data.repositories.timetable.TimetableRepository
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.afterLoading
import io.github.wulkanowy.utils.flowWithResourceIn
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
@ -30,14 +29,13 @@ import java.time.LocalDate.ofEpochDay
import javax.inject.Inject
class TimetablePresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val timetableRepository: TimetableRepository,
private val semesterRepository: SemesterRepository,
private val prefRepository: PreferencesRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<TimetableView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<TimetableView>(errorHandler, studentRepository) {
private var baseDate: LocalDate = now().nextOrSameSchoolDay

View File

@ -8,7 +8,6 @@ import io.github.wulkanowy.data.repositories.semester.SemesterRepository
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.afterLoading
import io.github.wulkanowy.utils.flowWithResourceIn
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
@ -27,13 +26,12 @@ import java.time.LocalDate.ofEpochDay
import javax.inject.Inject
class CompletedLessonsPresenter @Inject constructor(
schedulers: SchedulersProvider,
studentRepository: StudentRepository,
private val completedLessonsErrorHandler: CompletedLessonsErrorHandler,
private val semesterRepository: SemesterRepository,
private val completedLessonsRepository: CompletedLessonsRepository,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<CompletedLessonsView>(completedLessonsErrorHandler, studentRepository, schedulers) {
) : BasePresenter<CompletedLessonsView>(completedLessonsErrorHandler, studentRepository) {
private var baseDate: LocalDate = now().nextOrSameSchoolDay

View File

@ -8,18 +8,16 @@ 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.SchedulersProvider
import io.github.wulkanowy.utils.flowWithResource
import kotlinx.coroutines.flow.onEach
import timber.log.Timber
import javax.inject.Inject
class TimetableWidgetConfigurePresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val sharedPref: SharedPrefProvider
) : BasePresenter<TimetableWidgetConfigureView>(errorHandler, studentRepository, schedulers) {
) : BasePresenter<TimetableWidgetConfigureView>(errorHandler, studentRepository) {
private var appWidgetId: Int? = null

View File

@ -12,7 +12,6 @@ import android.widget.AdapterView.INVALID_POSITION
import android.widget.RemoteViews
import android.widget.RemoteViewsService
import io.github.wulkanowy.R
import io.github.wulkanowy.data.Status
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
@ -22,14 +21,10 @@ import io.github.wulkanowy.data.repositories.timetable.TimetableRepository
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.utils.SchedulersProvider
import io.github.wulkanowy.utils.getCompatColor
import io.github.wulkanowy.utils.toFirstResult
import io.github.wulkanowy.utils.toFormattedString
import io.reactivex.Maybe
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.takeWhile
import kotlinx.coroutines.rx2.rxMaybe
import kotlinx.coroutines.rx2.rxSingle
import kotlinx.coroutines.runBlocking
import timber.log.Timber
import java.time.LocalDate
@ -39,7 +34,6 @@ class TimetableWidgetFactory(
private val semesterRepository: SemesterRepository,
private val prefRepository: PreferencesRepository,
private val sharedPref: SharedPrefProvider,
private val schedulers: SchedulersProvider,
private val context: Context,
private val intent: Intent?
) : RemoteViewsService.RemoteViewsFactory {
@ -74,7 +68,7 @@ class TimetableWidgetFactory(
val studentId = sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0)
updateTheme(appWidgetId)
updateLessons(date, studentId)
lessons = getLessons(date, studentId)
}
}
@ -103,30 +97,23 @@ class TimetableWidgetFactory(
}
}
private fun updateLessons(date: LocalDate, studentId: Long) {
lessons = try {
rxSingle { studentRepository.isStudentSaved() }
.filter { true }
.flatMap { rxMaybe { studentRepository.getSavedStudents() } }
.flatMap {
val student = it.singleOrNull { student -> student.id == studentId }
private fun getLessons(date: LocalDate, studentId: Long) = try {
runBlocking {
if (!studentRepository.isStudentSaved()) return@runBlocking emptyList<Timetable>()
if (student != null) Maybe.just(student)
else Maybe.empty()
}
.flatMap { student ->
rxMaybe { semesterRepository.getCurrentSemester(student) }.flatMap { semester ->
rxMaybe { timetableRepository.getTimetable(student, semester, date, date, true).takeWhile { it.status == Status.LOADING }.first().data }
}
}
.map { items -> items.sortedWith(compareBy({ it.number }, { !it.isStudentPlan })) }
.map { lessons -> lessons.filter { if (prefRepository.showWholeClassPlan == "no") it.isStudentPlan else true } }
.subscribeOn(schedulers.backgroundThread)
.blockingGet(emptyList())
} catch (e: Exception) {
Timber.e(e, "An error has occurred in timetable widget factory")
emptyList()
val students = studentRepository.getSavedStudents()
val student = students.singleOrNull { student -> student.id == studentId }
?: return@runBlocking emptyList<Timetable>()
val semester = semesterRepository.getCurrentSemester(student)
timetableRepository.getTimetable(student, semester, date, date, false)
.toFirstResult().data.orEmpty()
.sortedWith(compareBy({ it.number }, { !it.isStudentPlan }))
.filter { if (prefRepository.showWholeClassPlan == "no") it.isStudentPlan else true }
}
} catch (e: Exception) {
Timber.e(e, "An error has occurred in timetable widget factory")
emptyList<Timetable>()
}
@SuppressLint("DefaultLocale")

View File

@ -25,14 +25,12 @@ import io.github.wulkanowy.services.widgets.TimetableWidgetService
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
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.reactivex.Maybe
import kotlinx.coroutines.rx2.rxMaybe
import kotlinx.coroutines.rx2.rxSingle
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import timber.log.Timber
import java.time.LocalDate
import java.time.LocalDate.now
@ -49,9 +47,6 @@ class TimetableWidgetProvider : BroadcastReceiver() {
@Inject
lateinit var sharedPref: SharedPrefProvider
@Inject
lateinit var schedulers: SchedulersProvider
@Inject
lateinit var analytics: FirebaseAnalyticsHelper
@ -80,13 +75,15 @@ class TimetableWidgetProvider : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
AndroidInjection.inject(this, context)
when (intent.action) {
ACTION_APPWIDGET_UPDATE -> onUpdate(context, intent)
ACTION_APPWIDGET_DELETED -> onDelete(intent)
GlobalScope.launch {
when (intent.action) {
ACTION_APPWIDGET_UPDATE -> onUpdate(context, intent)
ACTION_APPWIDGET_DELETED -> onDelete(intent)
}
}
}
private fun onUpdate(context: Context, intent: Intent) {
private suspend fun onUpdate(context: Context, intent: Intent) {
if (intent.getStringExtra(EXTRA_BUTTON_TYPE) === null) {
intent.getIntArrayExtra(EXTRA_APPWIDGET_IDS)?.forEach { appWidgetId ->
val student = getStudent(sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0), appWidgetId)
@ -170,8 +167,9 @@ class TimetableWidgetProvider : BroadcastReceiver() {
}
with(appWidgetManager) {
notifyAppWidgetViewDataChanged(appWidgetId, R.id.timetableWidgetList)
updateAppWidget(appWidgetId, remoteView)
notifyAppWidgetViewDataChanged(appWidgetId, R.id.timetableWidgetList)
Timber.d("TimetableWidgetProvider updated")
}
}
@ -184,31 +182,22 @@ class TimetableWidgetProvider : BroadcastReceiver() {
}, FLAG_UPDATE_CURRENT)
}
private fun getStudent(studentId: Long, appWidgetId: Int): Student? {
return try {
rxSingle { studentRepository.isStudentSaved() }
.filter { true }
.flatMap { rxMaybe { studentRepository.getSavedStudents(false) } }
.flatMap { students ->
val student = students.singleOrNull { student -> student.id == studentId }
when {
student != null -> Maybe.just(student)
studentId != 0L -> {
rxSingle { studentRepository.isCurrentStudentSet() }
.filter { true }
.flatMap { rxMaybe { studentRepository.getCurrentStudent(false) } }
.doOnSuccess { sharedPref.putLong(getStudentWidgetKey(appWidgetId), it.id) }
}
else -> Maybe.empty()
}
private suspend fun getStudent(studentId: Long, appWidgetId: Int) = try {
val students = studentRepository.getSavedStudents(false)
val student = students.singleOrNull { student -> student.id == studentId }
when {
student != null -> student
studentId != 0L && studentRepository.isCurrentStudentSet() -> {
studentRepository.getCurrentStudent(false).also {
sharedPref.putLong(getStudentWidgetKey(appWidgetId), it.id)
}
.subscribeOn(schedulers.backgroundThread)
.blockingGet()
} catch (e: Exception) {
if (e.cause !is NoCurrentStudentException) {
Timber.e(e, "An error has occurred in timetable widget provider")
}
null
else -> null
}
} catch (e: Exception) {
if (e.cause !is NoCurrentStudentException) {
Timber.e(e, "An error has occurred in timetable widget provider")
}
null
}
}

View File

@ -5,10 +5,12 @@ import io.github.wulkanowy.data.Status
import kotlinx.coroutines.flow.Flow
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
inline fun <ResultType, RequestType> networkBoundResource(
showSavedOnLoading: Boolean = true,
@ -91,3 +93,7 @@ fun <T> flowWithResourceIn(block: suspend () -> Flow<Resource<T>>) = flow {
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()

View File

@ -1,14 +0,0 @@
package io.github.wulkanowy.utils
import io.reactivex.Scheduler
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
open class SchedulersProvider {
open val mainThread: Scheduler
get() = AndroidSchedulers.mainThread()
open val backgroundThread: Scheduler
get() = Schedulers.io()
}

View File

@ -1,15 +0,0 @@
package io.github.wulkanowy
import io.github.wulkanowy.utils.SchedulersProvider
import io.reactivex.Scheduler
import io.reactivex.schedulers.Schedulers
class TestSchedulersProvider : SchedulersProvider() {
override val backgroundThread: Scheduler
get() = Schedulers.trampoline()
override val mainThread: Scheduler
get() = Schedulers.trampoline()
}

View File

@ -1,6 +1,5 @@
package io.github.wulkanowy.ui.modules.login
import io.github.wulkanowy.TestSchedulersProvider
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.mockk.MockKAnnotations
import io.mockk.clearMocks
@ -29,7 +28,7 @@ class LoginPresenterTest {
MockKAnnotations.init(this)
clearMocks(loginView)
presenter = LoginPresenter(TestSchedulersProvider(), errorHandler, studentRepository)
presenter = LoginPresenter(errorHandler, studentRepository)
presenter.onAttachView(loginView)
}

View File

@ -1,7 +1,6 @@
package io.github.wulkanowy.ui.modules.login.form
import io.github.wulkanowy.MainCoroutineRule
import io.github.wulkanowy.TestSchedulersProvider
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
@ -52,7 +51,7 @@ class LoginFormPresenterTest {
every { loginFormView.setErrorPassRequired(any()) } just Runs
every { loginFormView.setErrorUsernameRequired() } just Runs
presenter = LoginFormPresenter(TestSchedulersProvider(), repository, errorHandler, analytics)
presenter = LoginFormPresenter(repository, errorHandler, analytics)
presenter.onAttachView(loginFormView)
}

View File

@ -1,7 +1,6 @@
package io.github.wulkanowy.ui.modules.login.studentselect
import io.github.wulkanowy.MainCoroutineRule
import io.github.wulkanowy.TestSchedulersProvider
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
@ -53,7 +52,7 @@ class LoginStudentSelectPresenterTest {
every { loginStudentSelectView.showProgress(any()) } just Runs
every { loginStudentSelectView.showContent(any()) } just Runs
presenter = LoginStudentSelectPresenter(TestSchedulersProvider(), studentRepository, errorHandler, analytics)
presenter = LoginStudentSelectPresenter(studentRepository, errorHandler, analytics)
presenter.onAttachView(loginStudentSelectView, null)
}

View File

@ -1,6 +1,5 @@
package io.github.wulkanowy.ui.modules.main
import io.github.wulkanowy.TestSchedulersProvider
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.services.sync.SyncManager
@ -48,7 +47,7 @@ class MainPresenterTest {
every { mainView.startMenuIndex } returns 1
every { mainView.startMenuMoreIndex } returns 1
every { mainView.initView() } just Runs
presenter = MainPresenter(TestSchedulersProvider(), errorHandler, studentRepository, prefRepository, syncManager, analytics)
presenter = MainPresenter(errorHandler, studentRepository, prefRepository, syncManager, analytics)
presenter.onAttachView(mainView, null)
}

View File

@ -1,7 +1,6 @@
package io.github.wulkanowy.ui.modules.splash
import io.github.wulkanowy.MainCoroutineRule
import io.github.wulkanowy.TestSchedulersProvider
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.ErrorHandler
import io.mockk.MockKAnnotations
@ -31,7 +30,7 @@ class SplashPresenterTest {
@Before
fun setUp() {
MockKAnnotations.init(this)
presenter = SplashPresenter(TestSchedulersProvider(), errorHandler, studentRepository)
presenter = SplashPresenter(errorHandler, studentRepository)
}
@Test