forked from github/wulkanowy-mirror
Logger refactor (#175)
This commit is contained in:
parent
7f6f632b73
commit
5e30c8e949
@ -113,6 +113,7 @@ dependencies {
|
|||||||
|
|
||||||
implementation "com.jakewharton.timber:timber:4.7.1"
|
implementation "com.jakewharton.timber:timber:4.7.1"
|
||||||
implementation "at.favre.lib:slf4j-timber:1.0.1"
|
implementation "at.favre.lib:slf4j-timber:1.0.1"
|
||||||
|
implementation 'com.akaita.java:rxjava2-debug:1.3.0'
|
||||||
implementation("com.crashlytics.sdk.android:crashlytics:2.9.5@aar") {
|
implementation("com.crashlytics.sdk.android:crashlytics:2.9.5@aar") {
|
||||||
transitive = true
|
transitive = true
|
||||||
}
|
}
|
||||||
@ -125,7 +126,7 @@ dependencies {
|
|||||||
testImplementation "junit:junit:4.12"
|
testImplementation "junit:junit:4.12"
|
||||||
testImplementation "io.mockk:mockk:1.8.9"
|
testImplementation "io.mockk:mockk:1.8.9"
|
||||||
testImplementation "org.mockito:mockito-inline:2.23.0"
|
testImplementation "org.mockito:mockito-inline:2.23.0"
|
||||||
testImplementation 'org.threeten:threetenbp:1.3.7'
|
testImplementation 'org.threeten:threetenbp:1.3.8'
|
||||||
|
|
||||||
androidTestImplementation 'androidx.test:core:1.0.0'
|
androidTestImplementation 'androidx.test:core:1.0.0'
|
||||||
androidTestImplementation 'androidx.test:runner:1.1.0'
|
androidTestImplementation 'androidx.test:runner:1.1.0'
|
||||||
|
@ -2,6 +2,7 @@ package io.github.wulkanowy
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.multidex.MultiDex
|
import androidx.multidex.MultiDex
|
||||||
|
import com.akaita.java.rxjava2debug.RxJava2Debug
|
||||||
import com.crashlytics.android.Crashlytics
|
import com.crashlytics.android.Crashlytics
|
||||||
import com.crashlytics.android.answers.Answers
|
import com.crashlytics.android.answers.Answers
|
||||||
import com.crashlytics.android.core.CrashlyticsCore
|
import com.crashlytics.android.core.CrashlyticsCore
|
||||||
@ -29,22 +30,20 @@ class WulkanowyApp : DaggerApplication() {
|
|||||||
AndroidThreeTen.init(this)
|
AndroidThreeTen.init(this)
|
||||||
initializeFabric()
|
initializeFabric()
|
||||||
if (DEBUG) enableDebugLog()
|
if (DEBUG) enableDebugLog()
|
||||||
|
RxJava2Debug.enableRxJava2AssemblyTracking(arrayOf(BuildConfig.APPLICATION_ID))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun enableDebugLog() {
|
private fun enableDebugLog() {
|
||||||
Timber.plant(DebugLogTree)
|
Timber.plant(DebugLogTree())
|
||||||
FlexibleAdapter.enableLogs(Log.Level.DEBUG)
|
FlexibleAdapter.enableLogs(Log.Level.DEBUG)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initializeFabric() {
|
private fun initializeFabric() {
|
||||||
Fabric.with(Fabric.Builder(this)
|
Fabric.with(Fabric.Builder(this).kits(
|
||||||
.kits(Crashlytics.Builder()
|
Crashlytics.Builder().core(CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG || !BuildConfig.FABRIC_ENABLED).build()).build(),
|
||||||
.core(CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG || !BuildConfig.FABRIC_ENABLED).build())
|
Answers()
|
||||||
.build(),
|
).debuggable(BuildConfig.DEBUG).build())
|
||||||
Answers())
|
Timber.plant(CrashlyticsTree())
|
||||||
.debuggable(BuildConfig.DEBUG)
|
|
||||||
.build())
|
|
||||||
Timber.plant(CrashlyticsTree)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
|
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package io.github.wulkanowy.data
|
package io.github.wulkanowy.data
|
||||||
|
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
|
import com.akaita.java.rxjava2debug.RxJava2Debug
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.api.login.NotLoggedInException
|
import io.github.wulkanowy.api.login.NotLoggedInException
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -14,7 +15,7 @@ open class ErrorHandler @Inject constructor(private val resources: Resources) {
|
|||||||
var showErrorMessage: (String) -> Unit = {}
|
var showErrorMessage: (String) -> Unit = {}
|
||||||
|
|
||||||
open fun proceed(error: Throwable) {
|
open fun proceed(error: Throwable) {
|
||||||
Timber.e(error, "An exception occurred while the Wulkanowy was running")
|
Timber.e(RxJava2Debug.getEnhancedStackTrace(error), "An exception occurred while the Wulkanowy was running")
|
||||||
|
|
||||||
showErrorMessage((when (error) {
|
showErrorMessage((when (error) {
|
||||||
is UnknownHostException -> resources.getString(R.string.all_no_internet)
|
is UnknownHostException -> resources.getString(R.string.all_no_internet)
|
||||||
|
@ -4,6 +4,8 @@ import io.github.wulkanowy.api.Api
|
|||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
|
import okhttp3.logging.HttpLoggingInterceptor
|
||||||
|
import timber.log.Timber
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -75,6 +77,7 @@ class SessionRemote @Inject constructor(private val api: Api) {
|
|||||||
fun initApi(student: Student, reInitialize: Boolean = false) {
|
fun initApi(student: Student, reInitialize: Boolean = false) {
|
||||||
if (if (reInitialize) true else 0 == api.studentId) {
|
if (if (reInitialize) true else 0 == api.studentId) {
|
||||||
api.run {
|
api.run {
|
||||||
|
logLevel = HttpLoggingInterceptor.Level.NONE
|
||||||
email = student.email
|
email = student.email
|
||||||
password = student.password
|
password = student.password
|
||||||
symbol = student.symbol
|
symbol = student.symbol
|
||||||
@ -84,6 +87,9 @@ class SessionRemote @Inject constructor(private val api: Api) {
|
|||||||
studentId = student.studentId
|
studentId = student.studentId
|
||||||
loginType = Api.LoginType.valueOf(student.loginType)
|
loginType = Api.LoginType.valueOf(student.loginType)
|
||||||
notifyDataChanged()
|
notifyDataChanged()
|
||||||
|
setInterceptor(HttpLoggingInterceptor(HttpLoggingInterceptor.Logger {
|
||||||
|
Timber.d(it)
|
||||||
|
}).setLevel(HttpLoggingInterceptor.Level.BASIC))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,10 @@ package io.github.wulkanowy.ui.modules.about
|
|||||||
import com.mikepenz.aboutlibraries.Libs
|
import com.mikepenz.aboutlibraries.Libs
|
||||||
import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL1
|
import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL1
|
||||||
import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL2
|
import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL2
|
||||||
|
import com.mikepenz.aboutlibraries.Libs.SpecialButton.SPECIAL3
|
||||||
import io.github.wulkanowy.data.ErrorHandler
|
import io.github.wulkanowy.data.ErrorHandler
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AboutPresenter @Inject constructor(errorHandler: ErrorHandler) : BasePresenter<AboutView>(errorHandler) {
|
class AboutPresenter @Inject constructor(errorHandler: ErrorHandler) : BasePresenter<AboutView>(errorHandler) {
|
||||||
@ -12,9 +14,15 @@ class AboutPresenter @Inject constructor(errorHandler: ErrorHandler) : BasePrese
|
|||||||
fun onExtraSelect(type: Libs.SpecialButton?) {
|
fun onExtraSelect(type: Libs.SpecialButton?) {
|
||||||
view?.run {
|
view?.run {
|
||||||
when (type) {
|
when (type) {
|
||||||
SPECIAL1 -> openSourceWebView()
|
SPECIAL1 -> {
|
||||||
SPECIAL2 -> openIssuesWebView()
|
Timber.i("Opening github page")
|
||||||
else -> TODO()
|
openSourceWebView()
|
||||||
|
}
|
||||||
|
SPECIAL2 -> {
|
||||||
|
Timber.i("Opening issues page")
|
||||||
|
openIssuesWebView()
|
||||||
|
}
|
||||||
|
SPECIAL3 -> { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,13 @@ import io.github.wulkanowy.data.repositories.AttendanceRepository
|
|||||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.SessionRepository
|
import io.github.wulkanowy.data.repositories.SessionRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.utils.*
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
|
import io.github.wulkanowy.utils.isHolidays
|
||||||
|
import io.github.wulkanowy.utils.logEvent
|
||||||
|
import io.github.wulkanowy.utils.nextSchoolDay
|
||||||
|
import io.github.wulkanowy.utils.previousOrSameSchoolDay
|
||||||
|
import io.github.wulkanowy.utils.previousSchoolDay
|
||||||
|
import io.github.wulkanowy.utils.toFormattedString
|
||||||
import org.threeten.bp.LocalDate
|
import org.threeten.bp.LocalDate
|
||||||
import org.threeten.bp.LocalDate.now
|
import org.threeten.bp.LocalDate.now
|
||||||
import org.threeten.bp.LocalDate.ofEpochDay
|
import org.threeten.bp.LocalDate.ofEpochDay
|
||||||
@ -14,11 +20,11 @@ import java.util.concurrent.TimeUnit.MILLISECONDS
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AttendancePresenter @Inject constructor(
|
class AttendancePresenter @Inject constructor(
|
||||||
private val errorHandler: ErrorHandler,
|
private val errorHandler: ErrorHandler,
|
||||||
private val schedulers: SchedulersProvider,
|
private val schedulers: SchedulersProvider,
|
||||||
private val attendanceRepository: AttendanceRepository,
|
private val attendanceRepository: AttendanceRepository,
|
||||||
private val sessionRepository: SessionRepository,
|
private val sessionRepository: SessionRepository,
|
||||||
private val prefRepository: PreferencesRepository
|
private val prefRepository: PreferencesRepository
|
||||||
) : BasePresenter<AttendanceView>(errorHandler) {
|
) : BasePresenter<AttendanceView>(errorHandler) {
|
||||||
|
|
||||||
lateinit var currentDate: LocalDate
|
lateinit var currentDate: LocalDate
|
||||||
@ -34,11 +40,13 @@ class AttendancePresenter @Inject constructor(
|
|||||||
fun onPreviousDay() {
|
fun onPreviousDay() {
|
||||||
loadData(currentDate.previousSchoolDay)
|
loadData(currentDate.previousSchoolDay)
|
||||||
reloadView()
|
reloadView()
|
||||||
|
logEvent("Attendance day changed", mapOf("button" to "prev", "date" to currentDate.toFormattedString()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onNextDay() {
|
fun onNextDay() {
|
||||||
loadData(currentDate.nextSchoolDay)
|
loadData(currentDate.nextSchoolDay)
|
||||||
reloadView()
|
reloadView()
|
||||||
|
logEvent("Attendance day changed", mapOf("button" to "next", "date" to currentDate.toFormattedString()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onSwipeRefresh() {
|
fun onSwipeRefresh() {
|
||||||
@ -59,33 +67,34 @@ class AttendancePresenter @Inject constructor(
|
|||||||
disposable.apply {
|
disposable.apply {
|
||||||
clear()
|
clear()
|
||||||
add(sessionRepository.getSemesters()
|
add(sessionRepository.getSemesters()
|
||||||
.delay(200, MILLISECONDS)
|
.delay(200, MILLISECONDS)
|
||||||
.map { it.single { semester -> semester.current } }
|
.map { it.single { semester -> semester.current } }
|
||||||
.flatMap { attendanceRepository.getAttendance(it, date, date, forceRefresh) }
|
.flatMap { attendanceRepository.getAttendance(it, date, date, forceRefresh) }
|
||||||
.map { list ->
|
.map { list ->
|
||||||
if (prefRepository.showPresent) list
|
if (prefRepository.showPresent) list
|
||||||
else list.filter { !it.presence }
|
else list.filter { !it.presence }
|
||||||
|
}
|
||||||
|
.map { items -> items.map { AttendanceItem(it) } }
|
||||||
|
.map { items -> items.sortedBy { it.attendance.number } }
|
||||||
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
|
.observeOn(schedulers.mainThread)
|
||||||
|
.doFinally {
|
||||||
|
view?.run {
|
||||||
|
hideRefresh()
|
||||||
|
showProgress(false)
|
||||||
}
|
}
|
||||||
.map { items -> items.map { AttendanceItem(it) } }
|
}
|
||||||
.map { items -> items.sortedBy { it.attendance.number } }
|
.subscribe({
|
||||||
.subscribeOn(schedulers.backgroundThread)
|
view?.apply {
|
||||||
.observeOn(schedulers.mainThread)
|
updateData(it)
|
||||||
.doFinally {
|
showEmpty(it.isEmpty())
|
||||||
view?.run {
|
showContent(it.isNotEmpty())
|
||||||
hideRefresh()
|
|
||||||
showProgress(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.subscribe({
|
|
||||||
view?.apply {
|
|
||||||
updateData(it)
|
|
||||||
showEmpty(it.isEmpty())
|
|
||||||
showContent(it.isNotEmpty())
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
view?.run { showEmpty(isViewEmpty) }
|
|
||||||
errorHandler.proceed(it)
|
|
||||||
}
|
}
|
||||||
|
logEvent("Attendance load", mapOf("items" to it.size, "forceRefresh" to forceRefresh, "date" to currentDate.toFormattedString()))
|
||||||
|
}) {
|
||||||
|
view?.run { showEmpty(isViewEmpty) }
|
||||||
|
errorHandler.proceed(it)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,13 @@ import io.github.wulkanowy.data.db.entities.Exam
|
|||||||
import io.github.wulkanowy.data.repositories.ExamRepository
|
import io.github.wulkanowy.data.repositories.ExamRepository
|
||||||
import io.github.wulkanowy.data.repositories.SessionRepository
|
import io.github.wulkanowy.data.repositories.SessionRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.utils.*
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
|
import io.github.wulkanowy.utils.friday
|
||||||
|
import io.github.wulkanowy.utils.isHolidays
|
||||||
|
import io.github.wulkanowy.utils.logEvent
|
||||||
|
import io.github.wulkanowy.utils.monday
|
||||||
|
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
||||||
|
import io.github.wulkanowy.utils.toFormattedString
|
||||||
import org.threeten.bp.LocalDate
|
import org.threeten.bp.LocalDate
|
||||||
import org.threeten.bp.LocalDate.now
|
import org.threeten.bp.LocalDate.now
|
||||||
import org.threeten.bp.LocalDate.ofEpochDay
|
import org.threeten.bp.LocalDate.ofEpochDay
|
||||||
@ -14,10 +20,10 @@ import java.util.concurrent.TimeUnit.MILLISECONDS
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ExamPresenter @Inject constructor(
|
class ExamPresenter @Inject constructor(
|
||||||
private val errorHandler: ErrorHandler,
|
private val errorHandler: ErrorHandler,
|
||||||
private val schedulers: SchedulersProvider,
|
private val schedulers: SchedulersProvider,
|
||||||
private val examRepository: ExamRepository,
|
private val examRepository: ExamRepository,
|
||||||
private val sessionRepository: SessionRepository
|
private val sessionRepository: SessionRepository
|
||||||
) : BasePresenter<ExamView>(errorHandler) {
|
) : BasePresenter<ExamView>(errorHandler) {
|
||||||
|
|
||||||
lateinit var currentDate: LocalDate
|
lateinit var currentDate: LocalDate
|
||||||
@ -33,11 +39,13 @@ class ExamPresenter @Inject constructor(
|
|||||||
fun onPreviousWeek() {
|
fun onPreviousWeek() {
|
||||||
loadData(currentDate.minusDays(7))
|
loadData(currentDate.minusDays(7))
|
||||||
reloadView()
|
reloadView()
|
||||||
|
logEvent("Exam week changed", mapOf("button" to "prev", "date" to currentDate.toFormattedString()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onNextWeek() {
|
fun onNextWeek() {
|
||||||
loadData(currentDate.plusDays(7))
|
loadData(currentDate.plusDays(7))
|
||||||
reloadView()
|
reloadView()
|
||||||
|
logEvent("Exam week changed", mapOf("button" to "next", "date" to currentDate.toFormattedString()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onSwipeRefresh() {
|
fun onSwipeRefresh() {
|
||||||
@ -58,30 +66,31 @@ class ExamPresenter @Inject constructor(
|
|||||||
disposable.apply {
|
disposable.apply {
|
||||||
clear()
|
clear()
|
||||||
add(sessionRepository.getSemesters()
|
add(sessionRepository.getSemesters()
|
||||||
.delay(200, MILLISECONDS)
|
.delay(200, MILLISECONDS)
|
||||||
.map { it.single { semester -> semester.current } }
|
.map { it.single { semester -> semester.current } }
|
||||||
.flatMap {
|
.flatMap {
|
||||||
examRepository.getExams(it, currentDate.monday, currentDate.friday, forceRefresh)
|
examRepository.getExams(it, currentDate.monday, currentDate.friday, forceRefresh)
|
||||||
}.map { it.groupBy { exam -> exam.date }.toSortedMap() }
|
}.map { it.groupBy { exam -> exam.date }.toSortedMap() }
|
||||||
.map { createExamItems(it) }
|
.map { createExamItems(it) }
|
||||||
.subscribeOn(schedulers.backgroundThread)
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
.observeOn(schedulers.mainThread)
|
.observeOn(schedulers.mainThread)
|
||||||
.doFinally {
|
.doFinally {
|
||||||
view?.run {
|
view?.run {
|
||||||
hideRefresh()
|
hideRefresh()
|
||||||
showProgress(false)
|
showProgress(false)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.subscribe({
|
}
|
||||||
view?.apply {
|
.subscribe({
|
||||||
updateData(it)
|
view?.apply {
|
||||||
showEmpty(it.isEmpty())
|
updateData(it)
|
||||||
showContent(it.isNotEmpty())
|
showEmpty(it.isEmpty())
|
||||||
}
|
showContent(it.isNotEmpty())
|
||||||
}) {
|
}
|
||||||
view?.run { showEmpty(isViewEmpty) }
|
logEvent("Exam load", mapOf("items" to it.size, "forceRefresh" to forceRefresh, "date" to currentDate.toFormattedString()))
|
||||||
errorHandler.proceed(it)
|
}) {
|
||||||
})
|
view?.run { showEmpty(isViewEmpty) }
|
||||||
|
errorHandler.proceed(it)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +111,7 @@ class ExamPresenter @Inject constructor(
|
|||||||
showPreButton(!currentDate.minusDays(7).isHolidays)
|
showPreButton(!currentDate.minusDays(7).isHolidays)
|
||||||
showNextButton(!currentDate.plusDays(7).isHolidays)
|
showNextButton(!currentDate.plusDays(7).isHolidays)
|
||||||
updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " +
|
updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " +
|
||||||
currentDate.friday.toFormattedString("dd.MM"))
|
currentDate.friday.toFormattedString("dd.MM"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,9 @@ import io.github.wulkanowy.data.db.entities.Semester
|
|||||||
import io.github.wulkanowy.data.repositories.SessionRepository
|
import io.github.wulkanowy.data.repositories.SessionRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
|
import io.github.wulkanowy.utils.logEvent
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
|
import timber.log.Timber
|
||||||
import java.util.concurrent.TimeUnit.MILLISECONDS
|
import java.util.concurrent.TimeUnit.MILLISECONDS
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -48,6 +50,7 @@ class GradePresenter @Inject constructor(
|
|||||||
notifyChildrenSemesterChange()
|
notifyChildrenSemesterChange()
|
||||||
loadChild(it.currentPageIndex)
|
loadChild(it.currentPageIndex)
|
||||||
}
|
}
|
||||||
|
logEvent("Semester changed", mapOf("number" to index + 1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,15 +8,17 @@ import io.github.wulkanowy.data.repositories.SessionRepository
|
|||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import io.github.wulkanowy.utils.calcAverage
|
import io.github.wulkanowy.utils.calcAverage
|
||||||
|
import io.github.wulkanowy.utils.logEvent
|
||||||
import io.github.wulkanowy.utils.valueColor
|
import io.github.wulkanowy.utils.valueColor
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GradeDetailsPresenter @Inject constructor(
|
class GradeDetailsPresenter @Inject constructor(
|
||||||
private val errorHandler: ErrorHandler,
|
private val errorHandler: ErrorHandler,
|
||||||
private val schedulers: SchedulersProvider,
|
private val schedulers: SchedulersProvider,
|
||||||
private val gradeRepository: GradeRepository,
|
private val gradeRepository: GradeRepository,
|
||||||
private val sessionRepository: SessionRepository) : BasePresenter<GradeDetailsView>(errorHandler) {
|
private val sessionRepository: SessionRepository
|
||||||
|
) : BasePresenter<GradeDetailsView>(errorHandler) {
|
||||||
|
|
||||||
override fun onAttachView(view: GradeDetailsView) {
|
override fun onAttachView(view: GradeDetailsView) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
@ -25,27 +27,28 @@ class GradeDetailsPresenter @Inject constructor(
|
|||||||
|
|
||||||
fun onParentViewLoadData(semesterId: Int, forceRefresh: Boolean) {
|
fun onParentViewLoadData(semesterId: Int, forceRefresh: Boolean) {
|
||||||
disposable.add(sessionRepository.getSemesters()
|
disposable.add(sessionRepository.getSemesters()
|
||||||
.flatMap { gradeRepository.getGrades(it.first { item -> item.semesterId == semesterId }, forceRefresh) }
|
.flatMap { gradeRepository.getGrades(it.first { item -> item.semesterId == semesterId }, forceRefresh) }
|
||||||
.map { createGradeItems(it.groupBy { grade -> grade.subject }.toSortedMap()) }
|
.map { createGradeItems(it.groupBy { grade -> grade.subject }.toSortedMap()) }
|
||||||
.subscribeOn(schedulers.backgroundThread)
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
.observeOn(schedulers.mainThread)
|
.observeOn(schedulers.mainThread)
|
||||||
.doFinally {
|
.doFinally {
|
||||||
view?.run {
|
view?.run {
|
||||||
showRefresh(false)
|
showRefresh(false)
|
||||||
showProgress(false)
|
showProgress(false)
|
||||||
notifyParentDataLoaded(semesterId)
|
notifyParentDataLoaded(semesterId)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.subscribe({
|
}
|
||||||
view?.run {
|
.subscribe({
|
||||||
showEmpty(it.isEmpty())
|
view?.run {
|
||||||
showContent(it.isNotEmpty())
|
showEmpty(it.isEmpty())
|
||||||
updateData(it)
|
showContent(it.isNotEmpty())
|
||||||
}
|
updateData(it)
|
||||||
}) {
|
}
|
||||||
view?.run { showEmpty(isViewEmpty) }
|
logEvent("Grade details load", mapOf("items" to it.size, "forceRefresh" to forceRefresh))
|
||||||
errorHandler.proceed(it)
|
}) {
|
||||||
})
|
view?.run { showEmpty(isViewEmpty) }
|
||||||
|
errorHandler.proceed(it)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onGradeItemSelected(item: AbstractFlexibleItem<*>?) {
|
fun onGradeItemSelected(item: AbstractFlexibleItem<*>?) {
|
||||||
@ -92,16 +95,16 @@ class GradeDetailsPresenter @Inject constructor(
|
|||||||
return items.map {
|
return items.map {
|
||||||
it.value.calcAverage().let { average ->
|
it.value.calcAverage().let { average ->
|
||||||
GradeDetailsHeader(
|
GradeDetailsHeader(
|
||||||
subject = it.key,
|
subject = it.key,
|
||||||
average = formatAverage(average),
|
average = formatAverage(average),
|
||||||
number = view?.getGradeNumberString(it.value.size).orEmpty(),
|
number = view?.getGradeNumberString(it.value.size).orEmpty(),
|
||||||
newGrades = it.value.filter { grade -> !grade.isRead }.size
|
newGrades = it.value.filter { grade -> !grade.isRead }.size
|
||||||
).apply {
|
).apply {
|
||||||
subItems = it.value.map { item ->
|
subItems = it.value.map { item ->
|
||||||
GradeDetailsItem(
|
GradeDetailsItem(
|
||||||
grade = item,
|
grade = item,
|
||||||
weightString = view?.weightString.orEmpty(),
|
weightString = view?.weightString.orEmpty(),
|
||||||
valueColor = item.valueColor
|
valueColor = item.valueColor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,9 +121,9 @@ class GradeDetailsPresenter @Inject constructor(
|
|||||||
|
|
||||||
private fun updateGrade(grade: Grade) {
|
private fun updateGrade(grade: Grade) {
|
||||||
disposable.add(gradeRepository.updateGrade(grade)
|
disposable.add(gradeRepository.updateGrade(grade)
|
||||||
.subscribeOn(schedulers.backgroundThread)
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
.observeOn(schedulers.mainThread)
|
.observeOn(schedulers.mainThread)
|
||||||
.subscribe({}) { error -> errorHandler.proceed(error) })
|
.subscribe({}) { error -> errorHandler.proceed(error) })
|
||||||
Timber.d("Grade ${grade.id} updated")
|
Timber.d("Grade ${grade.id} updated")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,17 +8,18 @@ import io.github.wulkanowy.data.repositories.SessionRepository
|
|||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import io.github.wulkanowy.utils.calcAverage
|
import io.github.wulkanowy.utils.calcAverage
|
||||||
|
import io.github.wulkanowy.utils.logEvent
|
||||||
import java.lang.String.format
|
import java.lang.String.format
|
||||||
import java.util.Locale.FRANCE
|
import java.util.Locale.FRANCE
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GradeSummaryPresenter @Inject constructor(
|
class GradeSummaryPresenter @Inject constructor(
|
||||||
private val errorHandler: ErrorHandler,
|
private val errorHandler: ErrorHandler,
|
||||||
private val gradeSummaryRepository: GradeSummaryRepository,
|
private val gradeSummaryRepository: GradeSummaryRepository,
|
||||||
private val gradeRepository: GradeRepository,
|
private val gradeRepository: GradeRepository,
|
||||||
private val sessionRepository: SessionRepository,
|
private val sessionRepository: SessionRepository,
|
||||||
private val schedulers: SchedulersProvider)
|
private val schedulers: SchedulersProvider
|
||||||
: BasePresenter<GradeSummaryView>(errorHandler) {
|
) : BasePresenter<GradeSummaryView>(errorHandler) {
|
||||||
|
|
||||||
override fun onAttachView(view: GradeSummaryView) {
|
override fun onAttachView(view: GradeSummaryView) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
@ -27,43 +28,44 @@ class GradeSummaryPresenter @Inject constructor(
|
|||||||
|
|
||||||
fun onParentViewLoadData(semesterId: Int, forceRefresh: Boolean) {
|
fun onParentViewLoadData(semesterId: Int, forceRefresh: Boolean) {
|
||||||
disposable.add(sessionRepository.getSemesters()
|
disposable.add(sessionRepository.getSemesters()
|
||||||
.map { semester -> semester.first { it.semesterId == semesterId } }
|
.map { semester -> semester.first { it.semesterId == semesterId } }
|
||||||
.flatMap {
|
.flatMap {
|
||||||
gradeSummaryRepository.getGradesSummary(it, forceRefresh)
|
gradeSummaryRepository.getGradesSummary(it, forceRefresh)
|
||||||
.flatMap { gradesSummary ->
|
.flatMap { gradesSummary ->
|
||||||
gradeRepository.getGrades(it, forceRefresh)
|
gradeRepository.getGrades(it, forceRefresh)
|
||||||
.map { grades ->
|
.map { grades ->
|
||||||
grades.groupBy { grade -> grade.subject }
|
grades.groupBy { grade -> grade.subject }
|
||||||
.mapValues { entry -> entry.value.calcAverage() }
|
.mapValues { entry -> entry.value.calcAverage() }
|
||||||
.filterValues { value -> value != 0.0 }
|
.filterValues { value -> value != 0.0 }
|
||||||
.let { averages ->
|
.let { averages ->
|
||||||
createGradeSummaryItems(gradesSummary, averages) to
|
createGradeSummaryItems(gradesSummary, averages) to
|
||||||
GradeSummaryScrollableHeader(
|
GradeSummaryScrollableHeader(
|
||||||
formatAverage(gradesSummary.calcAverage()),
|
formatAverage(gradesSummary.calcAverage()),
|
||||||
formatAverage(averages.values.average())
|
formatAverage(averages.values.average())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
|
.observeOn(schedulers.mainThread)
|
||||||
|
.doFinally {
|
||||||
|
view?.run {
|
||||||
|
showRefresh(false)
|
||||||
|
showProgress(false)
|
||||||
|
notifyParentDataLoaded(semesterId)
|
||||||
}
|
}
|
||||||
.subscribeOn(schedulers.backgroundThread)
|
}.subscribe({
|
||||||
.observeOn(schedulers.mainThread)
|
view?.run {
|
||||||
.doFinally {
|
showEmpty(it.first.isEmpty())
|
||||||
view?.run {
|
showContent(it.first.isNotEmpty())
|
||||||
showRefresh(false)
|
updateDataSet(it.first, it.second)
|
||||||
showProgress(false)
|
}
|
||||||
notifyParentDataLoaded(semesterId)
|
logEvent("Grade summary load", mapOf("items" to it.first.size, "forceRefresh" to forceRefresh))
|
||||||
}
|
}) {
|
||||||
}.subscribe({
|
view?.run { showEmpty(isViewEmpty) }
|
||||||
view?.run {
|
errorHandler.proceed(it)
|
||||||
showEmpty(it.first.isEmpty())
|
})
|
||||||
showContent(it.first.isNotEmpty())
|
|
||||||
updateDataSet(it.first, it.second)
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
view?.run { showEmpty(isViewEmpty) }
|
|
||||||
errorHandler.proceed(it)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onSwipeRefresh() {
|
fun onSwipeRefresh() {
|
||||||
@ -88,24 +90,24 @@ class GradeSummaryPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createGradeSummaryItems(gradesSummary: List<GradeSummary>, averages: Map<String, Double>)
|
private fun createGradeSummaryItems(gradesSummary: List<GradeSummary>, averages: Map<String, Double>)
|
||||||
: List<GradeSummaryItem> {
|
: List<GradeSummaryItem> {
|
||||||
return gradesSummary.filter { !checkEmpty(it, averages) }
|
return gradesSummary.filter { !checkEmpty(it, averages) }
|
||||||
.flatMap { gradeSummary ->
|
.flatMap { gradeSummary ->
|
||||||
GradeSummaryHeader(
|
GradeSummaryHeader(
|
||||||
name = gradeSummary.subject,
|
name = gradeSummary.subject,
|
||||||
average = formatAverage(averages.getOrElse(gradeSummary.subject) { 0.0 }, "")
|
average = formatAverage(averages.getOrElse(gradeSummary.subject) { 0.0 }, "")
|
||||||
).let {
|
).let {
|
||||||
listOf(GradeSummaryItem(
|
listOf(GradeSummaryItem(
|
||||||
header = it,
|
header = it,
|
||||||
title = view?.predictedString.orEmpty(),
|
title = view?.predictedString.orEmpty(),
|
||||||
grade = gradeSummary.predictedGrade
|
grade = gradeSummary.predictedGrade
|
||||||
), GradeSummaryItem(
|
), GradeSummaryItem(
|
||||||
header = it,
|
header = it,
|
||||||
title = view?.finalString.orEmpty(),
|
title = view?.finalString.orEmpty(),
|
||||||
grade = gradeSummary.finalGrade
|
grade = gradeSummary.finalGrade
|
||||||
))
|
))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkEmpty(gradeSummary: GradeSummary, averages: Map<String, Double>): Boolean {
|
private fun checkEmpty(gradeSummary: GradeSummary, averages: Map<String, Double>): Boolean {
|
||||||
|
@ -4,13 +4,16 @@ import io.github.wulkanowy.data.repositories.SessionRepository
|
|||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
|
import io.github.wulkanowy.utils.logEvent
|
||||||
|
import io.github.wulkanowy.utils.logRegister
|
||||||
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class LoginFormPresenter @Inject constructor(
|
class LoginFormPresenter @Inject constructor(
|
||||||
private val schedulers: SchedulersProvider,
|
private val schedulers: SchedulersProvider,
|
||||||
private val errorHandler: LoginErrorHandler,
|
private val errorHandler: LoginErrorHandler,
|
||||||
private val sessionRepository: SessionRepository)
|
private val sessionRepository: SessionRepository
|
||||||
: BasePresenter<LoginFormView>(errorHandler) {
|
) : BasePresenter<LoginFormView>(errorHandler) {
|
||||||
|
|
||||||
private var wasEmpty = false
|
private var wasEmpty = false
|
||||||
|
|
||||||
@ -22,33 +25,39 @@ class LoginFormPresenter @Inject constructor(
|
|||||||
fun attemptLogin(email: String, password: String, symbol: String, endpoint: String) {
|
fun attemptLogin(email: String, password: String, symbol: String, endpoint: String) {
|
||||||
if (!validateCredentials(email, password, symbol)) return
|
if (!validateCredentials(email, password, symbol)) return
|
||||||
disposable.add(sessionRepository.getConnectedStudents(email, password, symbol, endpoint)
|
disposable.add(sessionRepository.getConnectedStudents(email, password, symbol, endpoint)
|
||||||
.observeOn(schedulers.mainThread)
|
.observeOn(schedulers.mainThread)
|
||||||
.subscribeOn(schedulers.backgroundThread)
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
.doOnSubscribe {
|
.doOnSubscribe {
|
||||||
view?.run {
|
view?.run {
|
||||||
hideSoftKeyboard()
|
hideSoftKeyboard()
|
||||||
showLoginProgress(true)
|
showLoginProgress(true)
|
||||||
errorHandler.doOnBadCredentials = {
|
errorHandler.doOnBadCredentials = {
|
||||||
setErrorPassIncorrect()
|
setErrorPassIncorrect()
|
||||||
showSoftKeyboard()
|
showSoftKeyboard()
|
||||||
}
|
Timber.i("Entered wrong username or password")
|
||||||
}
|
}
|
||||||
sessionRepository.clearCache()
|
|
||||||
}
|
}
|
||||||
.doFinally { view?.showLoginProgress(false) }
|
sessionRepository.clearCache()
|
||||||
.subscribe({
|
}
|
||||||
view?.run {
|
.doFinally { view?.showLoginProgress(false) }
|
||||||
if (it.isEmpty() && !wasEmpty) {
|
.subscribe({
|
||||||
showSymbolInput()
|
view?.run {
|
||||||
wasEmpty = true
|
if (it.isEmpty() && !wasEmpty) {
|
||||||
} else if (it.isEmpty() && wasEmpty) {
|
showSymbolInput()
|
||||||
showSymbolInput()
|
wasEmpty = true
|
||||||
setErrorSymbolIncorrect()
|
} else if (it.isEmpty() && wasEmpty) {
|
||||||
} else {
|
showSymbolInput()
|
||||||
switchNextView()
|
setErrorSymbolIncorrect()
|
||||||
}
|
logRegister("No student found", false, if (symbol.isEmpty()) "nil" else symbol, endpoint)
|
||||||
|
} else {
|
||||||
|
switchNextView()
|
||||||
|
logEvent("Found students", mapOf("students" to it.size, "symbol" to it.joinToString { student -> student.symbol }, "endpoint" to endpoint))
|
||||||
}
|
}
|
||||||
}, { errorHandler.proceed(it) }))
|
}
|
||||||
|
}, {
|
||||||
|
errorHandler.proceed(it)
|
||||||
|
logRegister(it.localizedMessage, false, if (symbol.isEmpty()) "nil" else symbol, endpoint)
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun validateCredentials(login: String, password: String, symbol: String): Boolean {
|
private fun validateCredentials(login: String, password: String, symbol: String): Boolean {
|
||||||
|
@ -5,13 +5,14 @@ import io.github.wulkanowy.data.db.entities.Student
|
|||||||
import io.github.wulkanowy.data.repositories.SessionRepository
|
import io.github.wulkanowy.data.repositories.SessionRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
|
import io.github.wulkanowy.utils.logRegister
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class LoginOptionsPresenter @Inject constructor(
|
class LoginOptionsPresenter @Inject constructor(
|
||||||
private val errorHandler: ErrorHandler,
|
private val errorHandler: ErrorHandler,
|
||||||
private val repository: SessionRepository,
|
private val repository: SessionRepository,
|
||||||
private val schedulers: SchedulersProvider)
|
private val schedulers: SchedulersProvider
|
||||||
: BasePresenter<LoginOptionsView>(errorHandler) {
|
) : BasePresenter<LoginOptionsView>(errorHandler) {
|
||||||
|
|
||||||
override fun onAttachView(view: LoginOptionsView) {
|
override fun onAttachView(view: LoginOptionsView) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
@ -20,25 +21,30 @@ class LoginOptionsPresenter @Inject constructor(
|
|||||||
|
|
||||||
fun refreshData() {
|
fun refreshData() {
|
||||||
disposable.add(repository.cachedStudents
|
disposable.add(repository.cachedStudents
|
||||||
.observeOn(schedulers.mainThread)
|
.observeOn(schedulers.mainThread)
|
||||||
.subscribeOn(schedulers.backgroundThread)
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
.doOnSubscribe { view?.showActionBar(true) }
|
.doOnSubscribe { view?.showActionBar(true) }
|
||||||
.doFinally { repository.clearCache() }
|
.doFinally { repository.clearCache() }
|
||||||
.subscribe({
|
.subscribe({
|
||||||
view?.updateData(it.map { student ->
|
view?.updateData(it.map { student ->
|
||||||
LoginOptionsItem(student)
|
LoginOptionsItem(student)
|
||||||
})
|
})
|
||||||
}, { errorHandler.proceed(it) }))
|
}, { errorHandler.proceed(it) }))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onSelectStudent(student: Student) {
|
fun onSelectStudent(student: Student) {
|
||||||
disposable.add(repository.saveStudent(student)
|
disposable.add(repository.saveStudent(student)
|
||||||
.subscribeOn(schedulers.backgroundThread)
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
.observeOn(schedulers.mainThread)
|
.observeOn(schedulers.mainThread)
|
||||||
.doOnSubscribe { _ ->
|
.doOnSubscribe {
|
||||||
view?.showLoginProgress(true)
|
view?.run {
|
||||||
view?.showActionBar(false)
|
showLoginProgress(true)
|
||||||
|
showActionBar(false)
|
||||||
}
|
}
|
||||||
.subscribe({ view?.openMainView() }, { errorHandler.proceed(it) }))
|
}
|
||||||
|
.subscribe({
|
||||||
|
logRegister("Success", true, student.symbol, student.endpoint)
|
||||||
|
view?.openMainView()
|
||||||
|
}, { errorHandler.proceed(it) }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import io.github.wulkanowy.ui.modules.grade.GradeFragment
|
|||||||
import io.github.wulkanowy.ui.modules.more.MoreFragment
|
import io.github.wulkanowy.ui.modules.more.MoreFragment
|
||||||
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
|
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
|
||||||
import io.github.wulkanowy.utils.getThemeAttrColor
|
import io.github.wulkanowy.utils.getThemeAttrColor
|
||||||
|
import io.github.wulkanowy.utils.logLogin
|
||||||
import io.github.wulkanowy.utils.safelyPopFragment
|
import io.github.wulkanowy.utils.safelyPopFragment
|
||||||
import io.github.wulkanowy.utils.setOnViewChangeListener
|
import io.github.wulkanowy.utils.setOnViewChangeListener
|
||||||
import kotlinx.android.synthetic.main.activity_main.*
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
|
@ -4,6 +4,7 @@ import io.github.wulkanowy.data.ErrorHandler
|
|||||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
import io.github.wulkanowy.services.job.ServiceHelper
|
import io.github.wulkanowy.services.job.ServiceHelper
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
|
import io.github.wulkanowy.utils.logLogin
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class MainPresenter @Inject constructor(
|
class MainPresenter @Inject constructor(
|
||||||
@ -21,6 +22,11 @@ class MainPresenter @Inject constructor(
|
|||||||
initView()
|
initView()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
when (initMenuIndex) {
|
||||||
|
1 -> logLogin("Grades")
|
||||||
|
3 -> logLogin("Timetable")
|
||||||
|
}
|
||||||
|
|
||||||
serviceHelper.startFullSyncService()
|
serviceHelper.startFullSyncService()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import io.github.wulkanowy.data.repositories.PreferencesRepository
|
|||||||
import io.github.wulkanowy.services.job.ServiceHelper
|
import io.github.wulkanowy.services.job.ServiceHelper
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.utils.isHolidays
|
import io.github.wulkanowy.utils.isHolidays
|
||||||
|
import io.github.wulkanowy.utils.logEvent
|
||||||
import org.threeten.bp.LocalDate.now
|
import org.threeten.bp.LocalDate.now
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -36,5 +37,7 @@ class SettingsPresenter @Inject constructor(
|
|||||||
view?.setTheme(preferencesRepository.currentTheme)
|
view?.setTheme(preferencesRepository.currentTheme)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logEvent("Setting changed", mapOf("name" to key))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import io.github.wulkanowy.data.ErrorHandler
|
|||||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.SessionRepository
|
import io.github.wulkanowy.data.repositories.SessionRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
|
import io.github.wulkanowy.utils.logLogin
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class SplashPresenter @Inject constructor(
|
class SplashPresenter @Inject constructor(
|
||||||
@ -16,7 +17,10 @@ class SplashPresenter @Inject constructor(
|
|||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
view.run {
|
view.run {
|
||||||
setCurrentThemeMode(preferencesRepository.currentTheme)
|
setCurrentThemeMode(preferencesRepository.currentTheme)
|
||||||
if (sessionRepository.isSessionSaved) openMainView() else openLoginView()
|
if (sessionRepository.isSessionSaved) {
|
||||||
|
logLogin("Open app")
|
||||||
|
openMainView()
|
||||||
|
} else openLoginView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,13 @@ import io.github.wulkanowy.data.ErrorHandler
|
|||||||
import io.github.wulkanowy.data.repositories.SessionRepository
|
import io.github.wulkanowy.data.repositories.SessionRepository
|
||||||
import io.github.wulkanowy.data.repositories.TimetableRepository
|
import io.github.wulkanowy.data.repositories.TimetableRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.utils.*
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
|
import io.github.wulkanowy.utils.isHolidays
|
||||||
|
import io.github.wulkanowy.utils.logEvent
|
||||||
|
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 org.threeten.bp.LocalDate
|
import org.threeten.bp.LocalDate
|
||||||
import org.threeten.bp.LocalDate.now
|
import org.threeten.bp.LocalDate.now
|
||||||
import org.threeten.bp.LocalDate.ofEpochDay
|
import org.threeten.bp.LocalDate.ofEpochDay
|
||||||
@ -13,10 +19,10 @@ import java.util.concurrent.TimeUnit.MILLISECONDS
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class TimetablePresenter @Inject constructor(
|
class TimetablePresenter @Inject constructor(
|
||||||
private val errorHandler: ErrorHandler,
|
private val errorHandler: ErrorHandler,
|
||||||
private val schedulers: SchedulersProvider,
|
private val schedulers: SchedulersProvider,
|
||||||
private val timetableRepository: TimetableRepository,
|
private val timetableRepository: TimetableRepository,
|
||||||
private val sessionRepository: SessionRepository
|
private val sessionRepository: SessionRepository
|
||||||
) : BasePresenter<TimetableView>(errorHandler) {
|
) : BasePresenter<TimetableView>(errorHandler) {
|
||||||
|
|
||||||
lateinit var currentDate: LocalDate
|
lateinit var currentDate: LocalDate
|
||||||
@ -32,11 +38,13 @@ class TimetablePresenter @Inject constructor(
|
|||||||
fun onPreviousDay() {
|
fun onPreviousDay() {
|
||||||
loadData(currentDate.previousSchoolDay)
|
loadData(currentDate.previousSchoolDay)
|
||||||
reloadView()
|
reloadView()
|
||||||
|
logEvent("Timetable day changed", mapOf("button" to "prev", "date" to currentDate.toFormattedString()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onNextDay() {
|
fun onNextDay() {
|
||||||
loadData(currentDate.nextSchoolDay)
|
loadData(currentDate.nextSchoolDay)
|
||||||
reloadView()
|
reloadView()
|
||||||
|
logEvent("Timetable day changed", mapOf("button" to "next", "date" to currentDate.toFormattedString()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onSwipeRefresh() {
|
fun onSwipeRefresh() {
|
||||||
@ -57,29 +65,30 @@ class TimetablePresenter @Inject constructor(
|
|||||||
disposable.apply {
|
disposable.apply {
|
||||||
clear()
|
clear()
|
||||||
add(sessionRepository.getSemesters()
|
add(sessionRepository.getSemesters()
|
||||||
.delay(200, MILLISECONDS)
|
.delay(200, MILLISECONDS)
|
||||||
.map { it.single { semester -> semester.current } }
|
.map { it.single { semester -> semester.current } }
|
||||||
.flatMap { timetableRepository.getTimetable(it, currentDate, currentDate, forceRefresh) }
|
.flatMap { timetableRepository.getTimetable(it, currentDate, currentDate, forceRefresh) }
|
||||||
.map { items -> items.map { TimetableItem(it, view?.roomString.orEmpty()) } }
|
.map { items -> items.map { TimetableItem(it, view?.roomString.orEmpty()) } }
|
||||||
.map { items -> items.sortedBy { it.lesson.number } }
|
.map { items -> items.sortedBy { it.lesson.number } }
|
||||||
.subscribeOn(schedulers.backgroundThread)
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
.observeOn(schedulers.mainThread)
|
.observeOn(schedulers.mainThread)
|
||||||
.doFinally {
|
.doFinally {
|
||||||
view?.run {
|
view?.run {
|
||||||
hideRefresh()
|
hideRefresh()
|
||||||
showProgress(false)
|
showProgress(false)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.subscribe({
|
}
|
||||||
view?.apply {
|
.subscribe({
|
||||||
updateData(it)
|
view?.apply {
|
||||||
showEmpty(it.isEmpty())
|
updateData(it)
|
||||||
showContent(it.isNotEmpty())
|
showEmpty(it.isEmpty())
|
||||||
}
|
showContent(it.isNotEmpty())
|
||||||
}) {
|
}
|
||||||
view?.run { showEmpty(isViewEmpty()) }
|
logEvent("Timetable load", mapOf("items" to it.size, "forceRefresh" to forceRefresh, "date" to currentDate.toFormattedString()))
|
||||||
errorHandler.proceed(it)
|
}) {
|
||||||
})
|
view?.run { showEmpty(isViewEmpty()) }
|
||||||
|
errorHandler.proceed(it)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ import io.github.wulkanowy.data.db.SharedPrefHelper
|
|||||||
import io.github.wulkanowy.services.widgets.TimetableWidgetService
|
import io.github.wulkanowy.services.widgets.TimetableWidgetService
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity.Companion.EXTRA_START_MENU_INDEX
|
import io.github.wulkanowy.ui.modules.main.MainActivity.Companion.EXTRA_START_MENU_INDEX
|
||||||
|
import io.github.wulkanowy.utils.logEvent
|
||||||
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
||||||
import io.github.wulkanowy.utils.nextSchoolDay
|
import io.github.wulkanowy.utils.nextSchoolDay
|
||||||
import io.github.wulkanowy.utils.previousSchoolDay
|
import io.github.wulkanowy.utils.previousSchoolDay
|
||||||
@ -78,16 +79,19 @@ class TimetableWidgetProvider : AppWidgetProvider() {
|
|||||||
AndroidInjection.inject(this, context)
|
AndroidInjection.inject(this, context)
|
||||||
intent?.let {
|
intent?.let {
|
||||||
val widgetKey = "timetable_widget_${it.getIntExtra(EXTRA_TOGGLED_WIDGET_ID, 0)}"
|
val widgetKey = "timetable_widget_${it.getIntExtra(EXTRA_TOGGLED_WIDGET_ID, 0)}"
|
||||||
when (it.getStringExtra(EXTRA_BUTTON_TYPE)) {
|
it.getStringExtra(EXTRA_BUTTON_TYPE).let { button ->
|
||||||
BUTTON_NEXT -> {
|
when (button) {
|
||||||
LocalDate.ofEpochDay(sharedPref.getLong(widgetKey, 0)).nextSchoolDay
|
BUTTON_NEXT -> {
|
||||||
.let { date -> sharedPref.putLong(widgetKey, date.toEpochDay(), true) }
|
LocalDate.ofEpochDay(sharedPref.getLong(widgetKey, 0)).nextSchoolDay
|
||||||
|
.let { date -> sharedPref.putLong(widgetKey, date.toEpochDay(), true) }
|
||||||
|
}
|
||||||
|
BUTTON_PREV -> {
|
||||||
|
LocalDate.ofEpochDay(sharedPref.getLong(widgetKey, 0)).previousSchoolDay
|
||||||
|
.let { date -> sharedPref.putLong(widgetKey, date.toEpochDay(), true) }
|
||||||
|
}
|
||||||
|
BUTTON_RESET -> sharedPref.putLong(widgetKey, LocalDate.now().nextOrSameSchoolDay.toEpochDay(), true)
|
||||||
}
|
}
|
||||||
BUTTON_PREV -> {
|
button?.also { btn -> if (btn.isNotBlank()) logEvent("Widget day changed", mapOf("button" to button)) }
|
||||||
LocalDate.ofEpochDay(sharedPref.getLong(widgetKey, 0)).previousSchoolDay
|
|
||||||
.let { date -> sharedPref.putLong(widgetKey, date.toEpochDay(), true) }
|
|
||||||
}
|
|
||||||
BUTTON_RESET -> sharedPref.putLong(widgetKey, LocalDate.now().nextOrSameSchoolDay.toEpochDay(), true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.onReceive(context, intent)
|
super.onReceive(context, intent)
|
||||||
|
48
app/src/main/java/io/github/wulkanowy/utils/FabricUtils.kt
Normal file
48
app/src/main/java/io/github/wulkanowy/utils/FabricUtils.kt
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package io.github.wulkanowy.utils
|
||||||
|
|
||||||
|
import com.crashlytics.android.answers.Answers
|
||||||
|
import com.crashlytics.android.answers.CustomEvent
|
||||||
|
import com.crashlytics.android.answers.LoginEvent
|
||||||
|
import com.crashlytics.android.answers.SignUpEvent
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
|
fun logLogin(method: String) {
|
||||||
|
try {
|
||||||
|
Answers.getInstance().logLogin(LoginEvent().putMethod(method))
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
Timber.d(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun logRegister(message: String, result: Boolean, symbol: String, endpoint: String) {
|
||||||
|
try {
|
||||||
|
Answers.getInstance().logSignUp(SignUpEvent()
|
||||||
|
.putMethod("Login activity")
|
||||||
|
.putSuccess(result)
|
||||||
|
.putCustomAttribute("symbol", symbol)
|
||||||
|
.putCustomAttribute("message", message)
|
||||||
|
.putCustomAttribute("endpoint", endpoint)
|
||||||
|
)
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
Timber.d(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> logEvent(name: String, params: Map<String, T>) {
|
||||||
|
try {
|
||||||
|
Answers.getInstance().logCustom(CustomEvent(name)
|
||||||
|
.apply {
|
||||||
|
params.forEach {
|
||||||
|
when {
|
||||||
|
it.value is String -> putCustomAttribute(it.key, it.value as String)
|
||||||
|
it.value is Number -> putCustomAttribute(it.key, it.value as Number)
|
||||||
|
it.value is Boolean -> putCustomAttribute(it.key, if ((it.value as Boolean)) "true" else "false")
|
||||||
|
else -> Timber.w("logEvent() unknown value type: ${it.value}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
Timber.d(e)
|
||||||
|
}
|
||||||
|
}
|
@ -3,25 +3,20 @@ package io.github.wulkanowy.utils
|
|||||||
import com.crashlytics.android.Crashlytics
|
import com.crashlytics.android.Crashlytics
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
object CrashlyticsTree : Timber.Tree() {
|
class DebugLogTree : Timber.DebugTree() {
|
||||||
|
|
||||||
|
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
||||||
|
super.log(priority, "Wulkanowy", message, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CrashlyticsTree : Timber.Tree() {
|
||||||
|
|
||||||
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
||||||
Crashlytics.setInt("priority", priority)
|
Crashlytics.setInt("priority", priority)
|
||||||
Crashlytics.setString("tag", tag)
|
Crashlytics.setString("tag", tag)
|
||||||
|
|
||||||
if (t == null) {
|
if (t == null) Crashlytics.log(message)
|
||||||
Crashlytics.log(message)
|
else Crashlytics.logException(t)
|
||||||
} else {
|
|
||||||
Crashlytics.setString("message", message)
|
|
||||||
Crashlytics.logException(t)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object DebugLogTree : Timber.DebugTree() {
|
|
||||||
|
|
||||||
override fun createStackElementTag(element: StackTraceElement): String? {
|
|
||||||
return super.createStackElementTag(element) + " - ${element.lineNumber}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -11,4 +11,4 @@ open class SchedulersProvider {
|
|||||||
|
|
||||||
open val backgroundThread: Scheduler
|
open val backgroundThread: Scheduler
|
||||||
get() = Schedulers.io()
|
get() = Schedulers.io()
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ class LoginFormPresenterTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun loginErrorTest() {
|
fun loginErrorTest() {
|
||||||
val testException = RuntimeException()
|
val testException = RuntimeException("test")
|
||||||
doReturn(Single.error<List<Student>>(testException))
|
doReturn(Single.error<List<Student>>(testException))
|
||||||
.`when`(repository).getConnectedStudents(anyString(), anyString(), anyString(), anyString())
|
.`when`(repository).getConnectedStudents(anyString(), anyString(), anyString(), anyString())
|
||||||
presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf")
|
presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user