Compare commits
42 Commits
Author | SHA1 | Date | |
---|---|---|---|
4b6b722f87 | |||
419675066f | |||
191b1ad022 | |||
792e44a9d0 | |||
ff5a47b0df | |||
7bf0acb703 | |||
ba5dbf90d8 | |||
54f41aaa63 | |||
1db42210e8 | |||
fb554a4a3b | |||
d8d13c73fb | |||
5c0160a24d | |||
ab7d30c995 | |||
1cfa1f15c0 | |||
2149a4db9f | |||
df57d16d21 | |||
2ff031005e | |||
b9ab85ee55 | |||
064998129e | |||
4044cdd9a5 | |||
1ee10a5902 | |||
27b1d076c7 | |||
c8b32fdb3b | |||
0b4434fdb6 | |||
699fbff082 | |||
4c295f2ab4 | |||
dcbaa170db | |||
c71b533645 | |||
63f2576ff1 | |||
b744a4182b | |||
0c4364609b | |||
3308d7fe6f | |||
2cdde78c54 | |||
428b599be0 | |||
3541ab81b8 | |||
7fa14e5077 | |||
cec1068f2e | |||
f737018548 | |||
9c01316178 | |||
c3a6f8253a | |||
d558c4db66 | |||
722886aaf2 |
@ -14,7 +14,7 @@ cache:
|
|||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- develop
|
- develop
|
||||||
- 0.18.0
|
- 0.18.2
|
||||||
|
|
||||||
android:
|
android:
|
||||||
licenses:
|
licenses:
|
||||||
|
@ -17,9 +17,10 @@ android {
|
|||||||
testApplicationId "io.github.tests.wulkanowy"
|
testApplicationId "io.github.tests.wulkanowy"
|
||||||
minSdkVersion 17
|
minSdkVersion 17
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 59
|
versionCode 61
|
||||||
versionName "0.18.0"
|
versionName "0.18.2"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
|
resValue "string", "app_name", "Wulkanowy"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
manifestPlaceholders = [
|
manifestPlaceholders = [
|
||||||
@ -56,6 +57,7 @@ android {
|
|||||||
signingConfig signingConfigs.release
|
signingConfig signingConfigs.release
|
||||||
}
|
}
|
||||||
debug {
|
debug {
|
||||||
|
resValue "string", "app_name", "Wulkanowy DEV " + defaultConfig.versionCode
|
||||||
applicationIdSuffix ".dev"
|
applicationIdSuffix ".dev"
|
||||||
versionNameSuffix "-dev"
|
versionNameSuffix "-dev"
|
||||||
testCoverageEnabled = project.hasProperty('coverage')
|
testCoverageEnabled = project.hasProperty('coverage')
|
||||||
@ -112,7 +114,7 @@ play {
|
|||||||
ext {
|
ext {
|
||||||
work_manager = "2.3.4"
|
work_manager = "2.3.4"
|
||||||
room = "2.2.5"
|
room = "2.2.5"
|
||||||
dagger = "2.27"
|
dagger = "2.28"
|
||||||
chucker = "3.2.0"
|
chucker = "3.2.0"
|
||||||
mockk = "1.9.2"
|
mockk = "1.9.2"
|
||||||
}
|
}
|
||||||
@ -122,7 +124,7 @@ configurations.all {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "io.github.wulkanowy:sdk:0.18.0"
|
implementation "io.github.wulkanowy:sdk:0.18.2"
|
||||||
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||||
implementation "androidx.core:core-ktx:1.2.0"
|
implementation "androidx.core:core-ktx:1.2.0"
|
||||||
@ -179,10 +181,10 @@ dependencies {
|
|||||||
implementation "io.coil-kt:coil:0.11.0"
|
implementation "io.coil-kt:coil:0.11.0"
|
||||||
implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
|
implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
|
||||||
|
|
||||||
playImplementation 'com.google.firebase:firebase-analytics:17.4.1'
|
playImplementation 'com.google.firebase:firebase-analytics:17.4.2'
|
||||||
playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx:19.0.6'
|
playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx:19.0.7'
|
||||||
playImplementation "com.google.firebase:firebase-inappmessaging-ktx:19.0.6"
|
playImplementation "com.google.firebase:firebase-inappmessaging-ktx:19.0.7"
|
||||||
playImplementation 'com.google.firebase:firebase-messaging:20.1.7'
|
playImplementation 'com.google.firebase:firebase-messaging:20.2.0'
|
||||||
playImplementation 'com.google.firebase:firebase-crashlytics:17.0.0'
|
playImplementation 'com.google.firebase:firebase-crashlytics:17.0.0'
|
||||||
playImplementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
|
playImplementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
|
||||||
|
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
<resources>
|
|
||||||
<string name="app_name">Wulkanowy DEV</string>
|
|
||||||
</resources>
|
|
@ -5,8 +5,6 @@ package io.github.wulkanowy.utils
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
fun initCrashlytics(context: Context, appInfo: AppInfo) {}
|
|
||||||
|
|
||||||
open class TimberTreeNoOp : Timber.Tree() {
|
open class TimberTreeNoOp : Timber.Tree() {
|
||||||
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {}
|
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
package io.github.wulkanowy.utils
|
package io.github.wulkanowy.utils
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
|
@Suppress("UNUSED_PARAMETER")
|
||||||
class FirebaseAnalyticsHelper @Inject constructor() {
|
class FirebaseAnalyticsHelper @Inject constructor() {
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
|
||||||
fun logEvent(name: String, vararg params: Pair<String, Any?>) {
|
fun logEvent(name: String, vararg params: Pair<String, Any?>) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setCurrentScreen(activity: Activity, name: String?) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.Inter
|
|||||||
import io.github.wulkanowy.data.db.entities.Attendance
|
import io.github.wulkanowy.data.db.entities.Attendance
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
@ -22,19 +22,19 @@ class AttendanceRepository @Inject constructor(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
fun getAttendance(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean): Single<List<Attendance>> {
|
fun getAttendance(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean): Single<List<Attendance>> {
|
||||||
return local.getAttendance(semester, start.monday, end.friday).filter { !forceRefresh }
|
return local.getAttendance(semester, start.monday, end.sunday).filter { !forceRefresh }
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
|
||||||
if (it) remote.getAttendance(student, semester, start.monday, end.friday)
|
if (it) remote.getAttendance(student, semester, start.monday, end.sunday)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}.flatMap { newAttendance ->
|
}.flatMap { newAttendance ->
|
||||||
local.getAttendance(semester, start.monday, end.friday)
|
local.getAttendance(semester, start.monday, end.sunday)
|
||||||
.toSingle(emptyList())
|
.toSingle(emptyList())
|
||||||
.doOnSuccess { oldAttendance ->
|
.doOnSuccess { oldAttendance ->
|
||||||
local.deleteAttendance(oldAttendance.uniqueSubtract(newAttendance))
|
local.deleteAttendance(oldAttendance.uniqueSubtract(newAttendance))
|
||||||
local.saveAttendance(newAttendance.uniqueSubtract(oldAttendance))
|
local.saveAttendance(newAttendance.uniqueSubtract(oldAttendance))
|
||||||
}
|
}
|
||||||
}.flatMap {
|
}.flatMap {
|
||||||
local.getAttendance(semester, start.monday, end.friday)
|
local.getAttendance(semester, start.monday, end.sunday)
|
||||||
.toSingle(emptyList())
|
.toSingle(emptyList())
|
||||||
}).map { list -> list.filter { it.date in start..end } }
|
}).map { list -> list.filter { it.date in start..end } }
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.Inter
|
|||||||
import io.github.wulkanowy.data.db.entities.CompletedLesson
|
import io.github.wulkanowy.data.db.entities.CompletedLesson
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
@ -22,20 +22,20 @@ class CompletedLessonsRepository @Inject constructor(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
fun getCompletedLessons(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<CompletedLesson>> {
|
fun getCompletedLessons(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<CompletedLesson>> {
|
||||||
return local.getCompletedLessons(semester, start.monday, end.friday).filter { !forceRefresh }
|
return local.getCompletedLessons(semester, start.monday, end.sunday).filter { !forceRefresh }
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.getCompletedLessons(student, semester, start.monday, end.friday)
|
if (it) remote.getCompletedLessons(student, semester, start.monday, end.sunday)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}.flatMap { new ->
|
}.flatMap { new ->
|
||||||
local.getCompletedLessons(semester, start.monday, end.friday)
|
local.getCompletedLessons(semester, start.monday, end.sunday)
|
||||||
.toSingle(emptyList())
|
.toSingle(emptyList())
|
||||||
.doOnSuccess { old ->
|
.doOnSuccess { old ->
|
||||||
local.deleteCompleteLessons(old.uniqueSubtract(new))
|
local.deleteCompleteLessons(old.uniqueSubtract(new))
|
||||||
local.saveCompletedLessons(new.uniqueSubtract(old))
|
local.saveCompletedLessons(new.uniqueSubtract(old))
|
||||||
}
|
}
|
||||||
}.flatMap {
|
}.flatMap {
|
||||||
local.getCompletedLessons(semester, start.monday, end.friday)
|
local.getCompletedLessons(semester, start.monday, end.sunday)
|
||||||
.toSingle(emptyList())
|
.toSingle(emptyList())
|
||||||
}).map { list -> list.filter { it.date in start..end } }
|
}).map { list -> list.filter { it.date in start..end } }
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.Inter
|
|||||||
import io.github.wulkanowy.data.db.entities.Exam
|
import io.github.wulkanowy.data.db.entities.Exam
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
@ -22,20 +22,20 @@ class ExamRepository @Inject constructor(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
fun getExams(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<Exam>> {
|
fun getExams(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<Exam>> {
|
||||||
return local.getExams(semester, start.monday, end.friday).filter { !forceRefresh }
|
return local.getExams(semester, start.monday, end.sunday).filter { !forceRefresh }
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.getExams(student, semester, start.monday, end.friday)
|
if (it) remote.getExams(student, semester, start.monday, end.sunday)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}.flatMap { new ->
|
}.flatMap { new ->
|
||||||
local.getExams(semester, start.monday, end.friday)
|
local.getExams(semester, start.monday, end.sunday)
|
||||||
.toSingle(emptyList())
|
.toSingle(emptyList())
|
||||||
.doOnSuccess { old ->
|
.doOnSuccess { old ->
|
||||||
local.deleteExams(old.uniqueSubtract(new))
|
local.deleteExams(old.uniqueSubtract(new))
|
||||||
local.saveExams(new.uniqueSubtract(old))
|
local.saveExams(new.uniqueSubtract(old))
|
||||||
}
|
}
|
||||||
}.flatMap {
|
}.flatMap {
|
||||||
local.getExams(semester, start.monday, end.friday)
|
local.getExams(semester, start.monday, end.sunday)
|
||||||
.toSingle(emptyList())
|
.toSingle(emptyList())
|
||||||
}).map { list -> list.filter { it.date in start..end } }
|
}).map { list -> list.filter { it.date in start..end } }
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.Inter
|
|||||||
import io.github.wulkanowy.data.db.entities.Homework
|
import io.github.wulkanowy.data.db.entities.Homework
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
@ -23,7 +23,7 @@ class HomeworkRepository @Inject constructor(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
fun getHomework(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<Homework>> {
|
fun getHomework(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<Homework>> {
|
||||||
return Single.fromCallable { start.monday to end.friday }.flatMap { (monday, friday) ->
|
return Single.fromCallable { start.monday to end.sunday }.flatMap { (monday, friday) ->
|
||||||
local.getHomework(semester, monday, friday).filter { !forceRefresh }
|
local.getHomework(semester, monday, friday).filter { !forceRefresh }
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
|
@ -39,7 +39,7 @@ class StudentRemote @Inject constructor(private val sdk: Sdk) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getStudentsMobileApi(token: String, pin: String, symbol: String): Single<List<Student>> {
|
fun getStudentsMobileApi(token: String, pin: String, symbol: String): Single<List<Student>> {
|
||||||
return sdk.getStudentsFromMobileApi(token, pin, symbol).map { mapStudents(it, "", "") }
|
return sdk.getStudentsFromMobileApi(token, pin, symbol, "").map { mapStudents(it, "", "") }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getStudentsScrapper(email: String, password: String, scrapperBaseUrl: String, symbol: String): Single<List<Student>> {
|
fun getStudentsScrapper(email: String, password: String, scrapperBaseUrl: String, symbol: String): Single<List<Student>> {
|
||||||
@ -47,6 +47,6 @@ class StudentRemote @Inject constructor(private val sdk: Sdk) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getStudentsHybrid(email: String, password: String, scrapperBaseUrl: String, symbol: String): Single<List<Student>> {
|
fun getStudentsHybrid(email: String, password: String, scrapperBaseUrl: String, symbol: String): Single<List<Student>> {
|
||||||
return sdk.getStudentsHybrid(email, password, scrapperBaseUrl, symbol).map { mapStudents(it, email, password) }
|
return sdk.getStudentsHybrid(email, password, scrapperBaseUrl, "", symbol).map { mapStudents(it, email, password) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import io.github.wulkanowy.data.db.entities.Semester
|
|||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.db.entities.Timetable
|
import io.github.wulkanowy.data.db.entities.Timetable
|
||||||
import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper
|
import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
@ -24,13 +24,13 @@ class TimetableRepository @Inject constructor(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
fun getTimetable(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<Timetable>> {
|
fun getTimetable(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<Timetable>> {
|
||||||
return Single.fromCallable { start.monday to end.friday }.flatMap { (monday, friday) ->
|
return Single.fromCallable { start.monday to end.sunday }.flatMap { (monday, sunday) ->
|
||||||
local.getTimetable(semester, monday, friday).filter { !forceRefresh }
|
local.getTimetable(semester, monday, sunday).filter { !forceRefresh }
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
|
||||||
if (it) remote.getTimetable(student, semester, monday, friday)
|
if (it) remote.getTimetable(student, semester, monday, sunday)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}.flatMap { new ->
|
}.flatMap { new ->
|
||||||
local.getTimetable(semester, monday, friday)
|
local.getTimetable(semester, monday, sunday)
|
||||||
.toSingle(emptyList())
|
.toSingle(emptyList())
|
||||||
.doOnSuccess { old ->
|
.doOnSuccess { old ->
|
||||||
local.deleteTimetable(old.uniqueSubtract(new).also { schedulerHelper.cancelScheduled(it) })
|
local.deleteTimetable(old.uniqueSubtract(new).also { schedulerHelper.cancelScheduled(it) })
|
||||||
@ -46,7 +46,7 @@ class TimetableRepository @Inject constructor(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}.flatMap {
|
}.flatMap {
|
||||||
local.getTimetable(semester, monday, friday).toSingle(emptyList())
|
local.getTimetable(semester, monday, sunday).toSingle(emptyList())
|
||||||
}).map { list -> list.filter { it.date in start..end }.also { schedulerHelper.scheduleNotifications(it, student) } }
|
}).map { list -> list.filter { it.date in start..end }.also { schedulerHelper.scheduleNotifications(it, student) } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.services.alarm
|
|||||||
import android.app.AlarmManager
|
import android.app.AlarmManager
|
||||||
import android.app.AlarmManager.RTC_WAKEUP
|
import android.app.AlarmManager.RTC_WAKEUP
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.app.PendingIntent.FLAG_CANCEL_CURRENT
|
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.core.app.AlarmManagerCompat
|
import androidx.core.app.AlarmManagerCompat
|
||||||
@ -55,7 +55,7 @@ class TimetableNotificationSchedulerHelper @Inject constructor(
|
|||||||
|
|
||||||
private fun cancelScheduledTo(range: ClosedRange<LocalDateTime>, requestCode: Int) {
|
private fun cancelScheduledTo(range: ClosedRange<LocalDateTime>, requestCode: Int) {
|
||||||
if (now() in range) cancelNotification()
|
if (now() in range) cancelNotification()
|
||||||
alarmManager.cancel(PendingIntent.getBroadcast(context, requestCode, Intent(), FLAG_CANCEL_CURRENT))
|
alarmManager.cancel(PendingIntent.getBroadcast(context, requestCode, Intent(), FLAG_UPDATE_CURRENT))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun cancelNotification() = NotificationManagerCompat.from(context).cancel(MainView.Section.TIMETABLE.id)
|
fun cancelNotification() = NotificationManagerCompat.from(context).cancel(MainView.Section.TIMETABLE.id)
|
||||||
@ -102,7 +102,7 @@ class TimetableNotificationSchedulerHelper @Inject constructor(
|
|||||||
PendingIntent.getBroadcast(context, getRequestCode(time, studentId), intent.also {
|
PendingIntent.getBroadcast(context, getRequestCode(time, studentId), intent.also {
|
||||||
it.putExtra(NOTIFICATION_ID, MainView.Section.TIMETABLE.id)
|
it.putExtra(NOTIFICATION_ID, MainView.Section.TIMETABLE.id)
|
||||||
it.putExtra(LESSON_TYPE, notificationType)
|
it.putExtra(LESSON_TYPE, notificationType)
|
||||||
}, FLAG_CANCEL_CURRENT)
|
}, FLAG_UPDATE_CURRENT)
|
||||||
)
|
)
|
||||||
Timber.d("TimetableNotification scheduled: type: $notificationType, subject: ${intent.getStringExtra(LESSON_TITLE)}, start: $time, student: $studentId")
|
Timber.d("TimetableNotification scheduled: type: $notificationType, subject: ${intent.getStringExtra(LESSON_TITLE)}, start: $time, student: $studentId")
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ class DebugChannel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun create() {
|
override fun create() {
|
||||||
if (appInfo.isDebug) return
|
if (!appInfo.isDebug) return
|
||||||
notificationManager.createNotificationChannel(
|
notificationManager.createNotificationChannel(
|
||||||
NotificationChannel(CHANNEL_ID, context.getString(R.string.channel_debug), IMPORTANCE_DEFAULT)
|
NotificationChannel(CHANNEL_ID, context.getString(R.string.channel_debug), IMPORTANCE_DEFAULT)
|
||||||
.apply {
|
.apply {
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.services.sync.works
|
|||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.repositories.attendance.AttendanceRepository
|
import io.github.wulkanowy.data.repositories.attendance.AttendanceRepository
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import org.threeten.bp.LocalDate.now
|
import org.threeten.bp.LocalDate.now
|
||||||
@ -12,7 +12,7 @@ import javax.inject.Inject
|
|||||||
class AttendanceWork @Inject constructor(private val attendanceRepository: AttendanceRepository) : Work {
|
class AttendanceWork @Inject constructor(private val attendanceRepository: AttendanceRepository) : Work {
|
||||||
|
|
||||||
override fun create(student: Student, semester: Semester): Completable {
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
return attendanceRepository.getAttendance(student, semester, now().monday, now().friday, true)
|
return attendanceRepository.getAttendance(student, semester, now().monday, now().sunday, true)
|
||||||
.ignoreElement()
|
.ignoreElement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.services.sync.works
|
|||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.repositories.completedlessons.CompletedLessonsRepository
|
import io.github.wulkanowy.data.repositories.completedlessons.CompletedLessonsRepository
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import org.threeten.bp.LocalDate.now
|
import org.threeten.bp.LocalDate.now
|
||||||
@ -14,7 +14,7 @@ class CompletedLessonWork @Inject constructor(
|
|||||||
) : Work {
|
) : Work {
|
||||||
|
|
||||||
override fun create(student: Student, semester: Semester): Completable {
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
return completedLessonsRepository.getCompletedLessons(student, semester, now().monday, now().friday, true)
|
return completedLessonsRepository.getCompletedLessons(student, semester, now().monday, now().sunday, true)
|
||||||
.ignoreElement()
|
.ignoreElement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.services.sync.works
|
|||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.repositories.exam.ExamRepository
|
import io.github.wulkanowy.data.repositories.exam.ExamRepository
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import org.threeten.bp.LocalDate.now
|
import org.threeten.bp.LocalDate.now
|
||||||
@ -12,6 +12,6 @@ import javax.inject.Inject
|
|||||||
class ExamWork @Inject constructor(private val examRepository: ExamRepository) : Work {
|
class ExamWork @Inject constructor(private val examRepository: ExamRepository) : Work {
|
||||||
|
|
||||||
override fun create(student: Student, semester: Semester): Completable {
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
return examRepository.getExams(student, semester, now().monday, now().friday, true).ignoreElement()
|
return examRepository.getExams(student, semester, now().monday, now().sunday, true).ignoreElement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.services.sync.works
|
|||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.repositories.homework.HomeworkRepository
|
import io.github.wulkanowy.data.repositories.homework.HomeworkRepository
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import org.threeten.bp.LocalDate.now
|
import org.threeten.bp.LocalDate.now
|
||||||
@ -12,6 +12,6 @@ import javax.inject.Inject
|
|||||||
class HomeworkWork @Inject constructor(private val homeworkRepository: HomeworkRepository) : Work {
|
class HomeworkWork @Inject constructor(private val homeworkRepository: HomeworkRepository) : Work {
|
||||||
|
|
||||||
override fun create(student: Student, semester: Semester): Completable {
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
return homeworkRepository.getHomework(student, semester, now().monday, now().friday, true).ignoreElement()
|
return homeworkRepository.getHomework(student, semester, now().monday, now().sunday, true).ignoreElement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.services.sync.works
|
|||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.repositories.timetable.TimetableRepository
|
import io.github.wulkanowy.data.repositories.timetable.TimetableRepository
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import org.threeten.bp.LocalDate.now
|
import org.threeten.bp.LocalDate.now
|
||||||
@ -12,7 +12,7 @@ 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 {
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
return timetableRepository.getTimetable(student, semester, now().monday, now().friday, true)
|
return timetableRepository.getTimetable(student, semester, now().monday, now().sunday, true)
|
||||||
.ignoreElement()
|
.ignoreElement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import android.view.ViewGroup
|
|||||||
import android.widget.HorizontalScrollView
|
import android.widget.HorizontalScrollView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import android.widget.Toast.LENGTH_LONG
|
import android.widget.Toast.LENGTH_LONG
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.databinding.DialogErrorBinding
|
import io.github.wulkanowy.databinding.DialogErrorBinding
|
||||||
@ -17,6 +18,7 @@ import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
|
|||||||
import io.github.wulkanowy.sdk.exception.ServiceUnavailableException
|
import io.github.wulkanowy.sdk.exception.ServiceUnavailableException
|
||||||
import io.github.wulkanowy.utils.AppInfo
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.getString
|
import io.github.wulkanowy.utils.getString
|
||||||
|
import io.github.wulkanowy.utils.openAppInMarket
|
||||||
import io.github.wulkanowy.utils.openEmailClient
|
import io.github.wulkanowy.utils.openEmailClient
|
||||||
import io.github.wulkanowy.utils.openInternetBrowser
|
import io.github.wulkanowy.utils.openInternetBrowser
|
||||||
import java.io.InterruptedIOException
|
import java.io.InterruptedIOException
|
||||||
@ -74,7 +76,9 @@ class ErrorDialog : BaseDialogFragment<DialogErrorBinding>() {
|
|||||||
Toast.makeText(context, R.string.all_copied, LENGTH_LONG).show()
|
Toast.makeText(context, R.string.all_copied, LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
errorDialogCancel.setOnClickListener { dismiss() }
|
errorDialogCancel.setOnClickListener { dismiss() }
|
||||||
errorDialogReport.setOnClickListener { openEmailClient(stringWriter.toString()) }
|
errorDialogReport.setOnClickListener {
|
||||||
|
openConfirmDialog { openEmailClient(stringWriter.toString()) }
|
||||||
|
}
|
||||||
errorDialogMessage.text = resources.getString(error)
|
errorDialogMessage.text = resources.getString(error)
|
||||||
errorDialogReport.isEnabled = when (error) {
|
errorDialogReport.isEnabled = when (error) {
|
||||||
is UnknownHostException,
|
is UnknownHostException,
|
||||||
@ -88,6 +92,17 @@ class ErrorDialog : BaseDialogFragment<DialogErrorBinding>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun openConfirmDialog(callback: () -> Unit) {
|
||||||
|
AlertDialog.Builder(requireContext())
|
||||||
|
.setTitle(R.string.dialog_error_check_update)
|
||||||
|
.setMessage(R.string.dialog_error_check_update_message)
|
||||||
|
.setNeutralButton(R.string.about_feedback) { _, _ -> callback() }
|
||||||
|
.setPositiveButton(R.string.dialog_error_check_update) { _, _ ->
|
||||||
|
requireContext().openAppInMarket(::showMessage)
|
||||||
|
}
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
private fun openEmailClient(content: String) {
|
private fun openEmailClient(content: String) {
|
||||||
requireContext().openEmailClient(
|
requireContext().openEmailClient(
|
||||||
chooserTitle = getString(R.string.about_feedback),
|
chooserTitle = getString(R.string.about_feedback),
|
||||||
|
@ -14,6 +14,7 @@ import io.github.wulkanowy.ui.modules.main.MainActivity
|
|||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import io.github.wulkanowy.utils.AppInfo
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.getCompatDrawable
|
import io.github.wulkanowy.utils.getCompatDrawable
|
||||||
|
import io.github.wulkanowy.utils.openAppInMarket
|
||||||
import io.github.wulkanowy.utils.openEmailClient
|
import io.github.wulkanowy.utils.openEmailClient
|
||||||
import io.github.wulkanowy.utils.openInternetBrowser
|
import io.github.wulkanowy.utils.openInternetBrowser
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -98,8 +99,12 @@ class AboutFragment : BaseFragment<FragmentAboutBinding>(R.layout.fragment_about
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun openAppInMarket() {
|
||||||
|
context?.openAppInMarket(::showMessage)
|
||||||
|
}
|
||||||
|
|
||||||
override fun openLogViewer() {
|
override fun openLogViewer() {
|
||||||
if (appInfo.isDebug) (activity as? MainActivity)?.pushView(LogViewerFragment.newInstance())
|
(activity as? MainActivity)?.pushView(LogViewerFragment.newInstance())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openDiscordInvite() {
|
override fun openDiscordInvite() {
|
||||||
@ -115,7 +120,7 @@ class AboutFragment : BaseFragment<FragmentAboutBinding>(R.layout.fragment_about
|
|||||||
chooserTitle = getString(R.string.about_feedback),
|
chooserTitle = getString(R.string.about_feedback),
|
||||||
email = "wulkanowyinc@gmail.com",
|
email = "wulkanowyinc@gmail.com",
|
||||||
subject = "Zgłoszenie błędu",
|
subject = "Zgłoszenie błędu",
|
||||||
body = requireContext().getString(R.string.about_feedback_template,
|
body = getString(R.string.about_feedback_template,
|
||||||
"${appInfo.systemManufacturer} ${appInfo.systemModel}", appInfo.systemVersion.toString(), appInfo.versionName
|
"${appInfo.systemManufacturer} ${appInfo.systemModel}", appInfo.systemVersion.toString(), appInfo.versionName
|
||||||
),
|
),
|
||||||
onActivityNotFound = {
|
onActivityNotFound = {
|
||||||
|
@ -3,6 +3,7 @@ package io.github.wulkanowy.ui.modules.about
|
|||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -12,6 +13,7 @@ class AboutPresenter @Inject constructor(
|
|||||||
schedulers: SchedulersProvider,
|
schedulers: SchedulersProvider,
|
||||||
errorHandler: ErrorHandler,
|
errorHandler: ErrorHandler,
|
||||||
studentRepository: StudentRepository,
|
studentRepository: StudentRepository,
|
||||||
|
private val appInfo: AppInfo,
|
||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BasePresenter<AboutView>(errorHandler, studentRepository, schedulers) {
|
) : BasePresenter<AboutView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
@ -27,7 +29,8 @@ class AboutPresenter @Inject constructor(
|
|||||||
when (name) {
|
when (name) {
|
||||||
versionRes?.first -> {
|
versionRes?.first -> {
|
||||||
Timber.i("Opening log viewer")
|
Timber.i("Opening log viewer")
|
||||||
openLogViewer()
|
if (appInfo.isDebug) openLogViewer()
|
||||||
|
else openAppInMarket()
|
||||||
analytics.logEvent("about_open", "name" to "log_viewer")
|
analytics.logEvent("about_open", "name" to "log_viewer")
|
||||||
}
|
}
|
||||||
feedbackRes?.first -> {
|
feedbackRes?.first -> {
|
||||||
|
@ -25,6 +25,8 @@ interface AboutView : BaseView {
|
|||||||
|
|
||||||
fun updateData(data: List<Triple<String, String, Drawable?>>)
|
fun updateData(data: List<Triple<String, String, Drawable?>>)
|
||||||
|
|
||||||
|
fun openAppInMarket()
|
||||||
|
|
||||||
fun openLogViewer()
|
fun openLogViewer()
|
||||||
|
|
||||||
fun openDiscordInvite()
|
fun openDiscordInvite()
|
||||||
|
@ -215,7 +215,12 @@ class AttendancePresenter @Inject constructor(
|
|||||||
showContent(it.isNotEmpty())
|
showContent(it.isNotEmpty())
|
||||||
showExcuseButton(it.any { item -> item.excusable })
|
showExcuseButton(it.any { item -> item.excusable })
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_attendance", "items" to it.size, "force_refresh" to forceRefresh)
|
analytics.logEvent(
|
||||||
|
"load_data",
|
||||||
|
"type" to "attendance",
|
||||||
|
"items" to it.size,
|
||||||
|
"force_refresh" to forceRefresh
|
||||||
|
)
|
||||||
}) {
|
}) {
|
||||||
Timber.i("Loading attendance result: An exception occurred")
|
Timber.i("Loading attendance result: An exception occurred")
|
||||||
errorHandler.dispatch(it)
|
errorHandler.dispatch(it)
|
||||||
|
@ -99,7 +99,13 @@ class AttendanceSummaryPresenter @Inject constructor(
|
|||||||
showContent(it.isNotEmpty())
|
showContent(it.isNotEmpty())
|
||||||
updateDataSet(it)
|
updateDataSet(it)
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_attendance_summary", "items" to it.size, "force_refresh" to forceRefresh, "item_id" to subjectId)
|
analytics.logEvent(
|
||||||
|
"load_data",
|
||||||
|
"type" to "attendance_summary",
|
||||||
|
"items" to it.size,
|
||||||
|
"force_refresh" to forceRefresh,
|
||||||
|
"item_id" to subjectId
|
||||||
|
)
|
||||||
}) {
|
}) {
|
||||||
Timber.i("Loading attendance summary result: An exception occurred")
|
Timber.i("Loading attendance summary result: An exception occurred")
|
||||||
errorHandler.dispatch(it)
|
errorHandler.dispatch(it)
|
||||||
|
@ -8,7 +8,7 @@ import io.github.wulkanowy.ui.base.BasePresenter
|
|||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
|
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
|
||||||
import io.github.wulkanowy.utils.isHolidays
|
import io.github.wulkanowy.utils.isHolidays
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
@ -110,7 +110,7 @@ class ExamPresenter @Inject constructor(
|
|||||||
add(studentRepository.getCurrentStudent()
|
add(studentRepository.getCurrentStudent()
|
||||||
.flatMap { student ->
|
.flatMap { student ->
|
||||||
semesterRepository.getCurrentSemester(student).flatMap { semester ->
|
semesterRepository.getCurrentSemester(student).flatMap { semester ->
|
||||||
examRepository.getExams(student, semester, currentDate.monday, currentDate.friday, forceRefresh)
|
examRepository.getExams(student, semester, currentDate.monday, currentDate.sunday, forceRefresh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.map { createExamItems(it) }
|
.map { createExamItems(it) }
|
||||||
@ -131,7 +131,12 @@ class ExamPresenter @Inject constructor(
|
|||||||
showErrorView(false)
|
showErrorView(false)
|
||||||
showContent(it.isNotEmpty())
|
showContent(it.isNotEmpty())
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_exam", "items" to it.size, "force_refresh" to forceRefresh)
|
analytics.logEvent(
|
||||||
|
"load_data",
|
||||||
|
"type" to "exam",
|
||||||
|
"items" to it.size,
|
||||||
|
"force_refresh" to forceRefresh
|
||||||
|
)
|
||||||
}) {
|
}) {
|
||||||
Timber.i("Loading exam result: An exception occurred")
|
Timber.i("Loading exam result: An exception occurred")
|
||||||
errorHandler.dispatch(it)
|
errorHandler.dispatch(it)
|
||||||
@ -176,7 +181,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.sunday.toFormattedString("dd.MM"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package io.github.wulkanowy.ui.modules.grade
|
package io.github.wulkanowy.ui.modules.grade
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.db.entities.Grade
|
||||||
|
import io.github.wulkanowy.data.db.entities.GradeSummary
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.repositories.grade.GradeRepository
|
import io.github.wulkanowy.data.repositories.grade.GradeRepository
|
||||||
@ -58,15 +60,14 @@ class GradeAverageProvider @Inject constructor(
|
|||||||
val isAnyAverage = summaries.any { it.average != .0 }
|
val isAnyAverage = summaries.any { it.average != .0 }
|
||||||
val allGrades = details.groupBy { it.subject }
|
val allGrades = details.groupBy { it.subject }
|
||||||
|
|
||||||
summaries.map { summary ->
|
summaries.emulateEmptySummaries(student, semester, allGrades.toList(), isAnyAverage).map { summary ->
|
||||||
val grades = allGrades[summary.subject].orEmpty()
|
val grades = allGrades[summary.subject].orEmpty()
|
||||||
GradeDetailsWithAverage(
|
GradeDetailsWithAverage(
|
||||||
subject = summary.subject,
|
subject = summary.subject,
|
||||||
average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) {
|
average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) {
|
||||||
grades.map {
|
(if (student.loginMode == Sdk.Mode.SCRAPPER.name)
|
||||||
if (student.loginMode == Sdk.Mode.SCRAPPER.name) it.changeModifier(plusModifier, minusModifier)
|
grades.map { it.changeModifier(plusModifier, minusModifier) }
|
||||||
else it
|
else grades).calcAverage()
|
||||||
}.calcAverage()
|
|
||||||
} else summary.average,
|
} else summary.average,
|
||||||
points = summary.pointsSum,
|
points = summary.pointsSum,
|
||||||
summary = summary,
|
summary = summary,
|
||||||
@ -75,4 +76,26 @@ class GradeAverageProvider @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun List<GradeSummary>.emulateEmptySummaries(student: Student, semester: Semester, grades: List<Pair<String, List<Grade>>>, calcAverage: Boolean): List<GradeSummary> {
|
||||||
|
if (isNotEmpty() && size == grades.size) return this
|
||||||
|
|
||||||
|
return grades.mapIndexed { i, (subject, details) ->
|
||||||
|
singleOrNull { it.subject == subject }?.let { return@mapIndexed it }
|
||||||
|
GradeSummary(
|
||||||
|
studentId = student.studentId,
|
||||||
|
semesterId = semester.semesterId,
|
||||||
|
position = i,
|
||||||
|
subject = subject,
|
||||||
|
predictedGrade = "",
|
||||||
|
finalGrade = "",
|
||||||
|
proposedPoints = "",
|
||||||
|
finalPoints = "",
|
||||||
|
pointsSum = "",
|
||||||
|
average = if (calcAverage) (if (student.loginMode == Sdk.Mode.SCRAPPER.name) {
|
||||||
|
details.map { it.changeModifier(plusModifier, minusModifier) }
|
||||||
|
} else details).calcAverage() else .0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,6 +133,7 @@ class GradePresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadChild(index: Int, forceRefresh: Boolean = false) {
|
private fun loadChild(index: Int, forceRefresh: Boolean = false) {
|
||||||
|
Timber.d("Load grade tab child. Selected semester: $selectedIndex, semesters: ${semesters.joinToString { it.semesterName.toString() }}")
|
||||||
semesters.first { it.semesterName == selectedIndex }.semesterId.also {
|
semesters.first { it.semesterName == selectedIndex }.semesterId.also {
|
||||||
if (forceRefresh || loadedSemesterId[index] != it) {
|
if (forceRefresh || loadedSemesterId[index] != it) {
|
||||||
Timber.i("Load grade child view index: $index")
|
Timber.i("Load grade child view index: $index")
|
||||||
|
@ -7,6 +7,7 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.recyclerview.widget.RecyclerView.NO_POSITION
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.Grade
|
import io.github.wulkanowy.data.db.entities.Grade
|
||||||
import io.github.wulkanowy.databinding.HeaderGradeDetailsBinding
|
import io.github.wulkanowy.databinding.HeaderGradeDetailsBinding
|
||||||
@ -14,6 +15,7 @@ import io.github.wulkanowy.databinding.ItemGradeDetailsBinding
|
|||||||
import io.github.wulkanowy.ui.base.BaseExpandableAdapter
|
import io.github.wulkanowy.ui.base.BaseExpandableAdapter
|
||||||
import io.github.wulkanowy.utils.getBackgroundColor
|
import io.github.wulkanowy.utils.getBackgroundColor
|
||||||
import io.github.wulkanowy.utils.toFormattedString
|
import io.github.wulkanowy.utils.toFormattedString
|
||||||
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<RecyclerView.ViewHolder>() {
|
class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<RecyclerView.ViewHolder>() {
|
||||||
@ -22,7 +24,7 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
|
|||||||
|
|
||||||
private var items = mutableListOf<GradeDetailsItem>()
|
private var items = mutableListOf<GradeDetailsItem>()
|
||||||
|
|
||||||
private var expandedPosition = RecyclerView.NO_POSITION
|
private var expandedPosition = NO_POSITION
|
||||||
|
|
||||||
private var isExpandable = false
|
private var isExpandable = false
|
||||||
|
|
||||||
@ -34,36 +36,53 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
|
|||||||
headers = data.filter { it.viewType == ViewType.HEADER }.toMutableList()
|
headers = data.filter { it.viewType == ViewType.HEADER }.toMutableList()
|
||||||
items = if (isExpanded) headers else data.toMutableList()
|
items = if (isExpanded) headers else data.toMutableList()
|
||||||
isExpandable = isExpanded
|
isExpandable = isExpanded
|
||||||
expandedPosition = RecyclerView.NO_POSITION
|
expandedPosition = NO_POSITION
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateDetailsItem(position: Int, grade: Grade) {
|
fun updateDetailsItem(position: Int, grade: Grade) {
|
||||||
|
if (items.getOrNull(position)?.viewType != ViewType.ITEM) {
|
||||||
|
Timber.e("Trying to update item $position on list ${items.size} size, expanded position: $expandedPosition")
|
||||||
|
return
|
||||||
|
}
|
||||||
items[position] = GradeDetailsItem(grade, ViewType.ITEM)
|
items[position] = GradeDetailsItem(grade, ViewType.ITEM)
|
||||||
notifyItemChanged(position)
|
notifyItemChanged(position)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getHeaderItem(subject: String): GradeDetailsItem {
|
fun getHeaderItem(subject: String): GradeDetailsItem {
|
||||||
return headers.single { (it.value as GradeDetailsHeader).subject == subject }
|
val candidates = headers.filter { (it.value as GradeDetailsHeader).subject == subject }
|
||||||
|
|
||||||
|
if (candidates.size > 1) {
|
||||||
|
Timber.e("Header with subject $subject found ${candidates.size} times! Expanded: $expandedPosition. Items: $candidates")
|
||||||
|
}
|
||||||
|
|
||||||
|
return candidates.first()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateHeaderItem(item: GradeDetailsItem) {
|
fun updateHeaderItem(item: GradeDetailsItem) {
|
||||||
headers[headers.indexOf(item)] = item
|
val headerPosition = headers.indexOf(item)
|
||||||
items[items.indexOf(item)] = item
|
val itemPosition = items.indexOf(item)
|
||||||
notifyItemChanged(items.indexOf(item))
|
|
||||||
|
if (headerPosition == NO_POSITION || itemPosition == NO_POSITION) {
|
||||||
|
Timber.e("Invalid update header positions! Header: $headerPosition, item: $itemPosition")
|
||||||
|
}
|
||||||
|
|
||||||
|
headers[headerPosition] = item
|
||||||
|
items[itemPosition] = item
|
||||||
|
notifyItemChanged(itemPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun collapseAll() {
|
fun collapseAll() {
|
||||||
if (expandedPosition != -1) {
|
if (expandedPosition != -1) {
|
||||||
refreshList(headers)
|
refreshList(headers)
|
||||||
expandedPosition = RecyclerView.NO_POSITION
|
expandedPosition = NO_POSITION
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
private fun refreshList(newItems: List<GradeDetailsItem>) {
|
private fun refreshList(newItems: MutableList<GradeDetailsItem>) {
|
||||||
val diffCallback = GradeDetailsDiffUtil(items, newItems)
|
val diffCallback = GradeDetailsDiffUtil(items, newItems)
|
||||||
val diffResult = DiffUtil.calculateDiff(diffCallback)
|
val diffResult = DiffUtil.calculateDiff(diffCallback)
|
||||||
items = newItems.toMutableList()
|
items = newItems
|
||||||
diffResult.dispatchUpdatesTo(this)
|
diffResult.dispatchUpdatesTo(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,23 +103,24 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
|
|||||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
when (holder) {
|
when (holder) {
|
||||||
is HeaderViewHolder -> bindHeaderViewHolder(
|
is HeaderViewHolder -> bindHeaderViewHolder(
|
||||||
binding = holder.binding,
|
holder = holder,
|
||||||
header = items[position].value as GradeDetailsHeader,
|
header = items[position].value as GradeDetailsHeader,
|
||||||
headerPosition = headers.indexOf(items[position]),
|
position = position
|
||||||
adapterPosition = position
|
|
||||||
)
|
)
|
||||||
is ItemViewHolder -> bindItemViewHolder(
|
is ItemViewHolder -> bindItemViewHolder(
|
||||||
binding = holder.binding,
|
holder = holder,
|
||||||
grade = items[position].value as Grade,
|
grade = items[position].value as Grade
|
||||||
position = position
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bindHeaderViewHolder(binding: HeaderGradeDetailsBinding, header: GradeDetailsHeader, headerPosition: Int, adapterPosition: Int) {
|
private fun bindHeaderViewHolder(holder: HeaderViewHolder, header: GradeDetailsHeader, position: Int) {
|
||||||
with(binding) {
|
val headerPosition = headers.indexOf(items[position])
|
||||||
|
val adapterPosition = holder.adapterPosition
|
||||||
|
|
||||||
|
with(holder.binding) {
|
||||||
gradeHeaderDivider.visibility = if (adapterPosition == 0) View.GONE else View.VISIBLE
|
gradeHeaderDivider.visibility = if (adapterPosition == 0) View.GONE else View.VISIBLE
|
||||||
gradeHeaderSubject.apply {
|
with(gradeHeaderSubject) {
|
||||||
text = header.subject
|
text = header.subject
|
||||||
maxLines = if (headerPosition == expandedPosition) 2 else 1
|
maxLines = if (headerPosition == expandedPosition) 2 else 1
|
||||||
}
|
}
|
||||||
@ -115,7 +135,7 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
|
|||||||
gradeHeaderContainer.setOnClickListener {
|
gradeHeaderContainer.setOnClickListener {
|
||||||
expandedPosition = if (expandedPosition == adapterPosition) -1 else adapterPosition
|
expandedPosition = if (expandedPosition == adapterPosition) -1 else adapterPosition
|
||||||
|
|
||||||
if (expandedPosition != RecyclerView.NO_POSITION) {
|
if (expandedPosition != NO_POSITION) {
|
||||||
refreshList(headers.toMutableList().apply {
|
refreshList(headers.toMutableList().apply {
|
||||||
addAll(headerPosition + 1, header.grades)
|
addAll(headerPosition + 1, header.grades)
|
||||||
})
|
})
|
||||||
@ -133,8 +153,8 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
private fun bindItemViewHolder(binding: ItemGradeDetailsBinding, grade: Grade, position: Int) {
|
private fun bindItemViewHolder(holder: ItemViewHolder, grade: Grade) {
|
||||||
with(binding) {
|
with(holder.binding) {
|
||||||
gradeItemValue.run {
|
gradeItemValue.run {
|
||||||
text = grade.entry
|
text = grade.entry
|
||||||
setBackgroundResource(grade.getBackgroundColor(colorTheme))
|
setBackgroundResource(grade.getBackgroundColor(colorTheme))
|
||||||
@ -148,7 +168,9 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
|
|||||||
gradeItemWeight.text = "${root.context.getString(R.string.grade_weight)}: ${grade.weight}"
|
gradeItemWeight.text = "${root.context.getString(R.string.grade_weight)}: ${grade.weight}"
|
||||||
gradeItemNote.visibility = if (!grade.isRead) View.VISIBLE else View.GONE
|
gradeItemNote.visibility = if (!grade.isRead) View.VISIBLE else View.GONE
|
||||||
|
|
||||||
root.setOnClickListener { onClickListener(grade, position) }
|
root.setOnClickListener {
|
||||||
|
holder.adapterPosition.let { if (it != NO_POSITION) onClickListener(grade, it) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ class GradeDetailsPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onGradeItemSelected(grade: Grade, position: Int) {
|
fun onGradeItemSelected(grade: Grade, position: Int) {
|
||||||
Timber.i("Select grade item ${grade.id}")
|
Timber.i("Select grade item ${grade.id}, position: $position")
|
||||||
view?.apply {
|
view?.apply {
|
||||||
showGradeDialog(grade, preferencesRepository.gradeColorTheme)
|
showGradeDialog(grade, preferencesRepository.gradeColorTheme)
|
||||||
if (!grade.isRead) {
|
if (!grade.isRead) {
|
||||||
@ -152,7 +152,12 @@ class GradeDetailsPresenter @Inject constructor(
|
|||||||
gradeColorTheme = preferencesRepository.gradeColorTheme
|
gradeColorTheme = preferencesRepository.gradeColorTheme
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_grade_details", "items" to grades.size, "force_refresh" to forceRefresh)
|
analytics.logEvent(
|
||||||
|
"load_data",
|
||||||
|
"type" to "grade_details",
|
||||||
|
"items" to grades.size,
|
||||||
|
"force_refresh" to forceRefresh
|
||||||
|
)
|
||||||
}) {
|
}) {
|
||||||
Timber.i("Loading grade details result: An exception occurred")
|
Timber.i("Loading grade details result: An exception occurred")
|
||||||
errorHandler.dispatch(it)
|
errorHandler.dispatch(it)
|
||||||
@ -171,19 +176,22 @@ class GradeDetailsPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createGradeItems(items: List<GradeDetailsWithAverage>): List<GradeDetailsItem> {
|
private fun createGradeItems(items: List<GradeDetailsWithAverage>): List<GradeDetailsItem> {
|
||||||
return items.filter { it.grades.isNotEmpty() }.map { (subject, average, points, _, grades) ->
|
return items
|
||||||
val subItems = grades.map {
|
.filter { it.grades.isNotEmpty() }
|
||||||
GradeDetailsItem(it, ViewType.ITEM)
|
.sortedBy { it.subject }
|
||||||
}
|
.map { (subject, average, points, _, grades) ->
|
||||||
|
val subItems = grades
|
||||||
|
.sortedByDescending { it.date }
|
||||||
|
.map { GradeDetailsItem(it, ViewType.ITEM) }
|
||||||
|
|
||||||
listOf(GradeDetailsItem(GradeDetailsHeader(
|
listOf(GradeDetailsItem(GradeDetailsHeader(
|
||||||
subject = subject,
|
subject = subject,
|
||||||
average = average,
|
average = average,
|
||||||
pointsSum = points,
|
pointsSum = points,
|
||||||
newGrades = grades.filter { grade -> !grade.isRead }.size,
|
newGrades = grades.filter { grade -> !grade.isRead }.size,
|
||||||
grades = subItems
|
grades = subItems
|
||||||
), ViewType.HEADER)) + if (preferencesRepository.isGradeExpandable) emptyList() else subItems
|
), ViewType.HEADER)) + if (preferencesRepository.isGradeExpandable) emptyList() else subItems
|
||||||
}.flatten()
|
}.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateGrade(grade: Grade) {
|
private fun updateGrade(grade: Grade) {
|
||||||
|
@ -174,7 +174,12 @@ class GradeStatisticsPresenter @Inject constructor(
|
|||||||
updateData(it, preferencesRepository.gradeColorTheme, preferencesRepository.showAllSubjectsOnStatisticsList)
|
updateData(it, preferencesRepository.gradeColorTheme, preferencesRepository.showAllSubjectsOnStatisticsList)
|
||||||
showSubjects(!preferencesRepository.showAllSubjectsOnStatisticsList)
|
showSubjects(!preferencesRepository.showAllSubjectsOnStatisticsList)
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_grade_statistics", "items" to it.size, "force_refresh" to forceRefresh)
|
analytics.logEvent(
|
||||||
|
"load_data",
|
||||||
|
"type" to "grade_statistics",
|
||||||
|
"items" to it.size,
|
||||||
|
"force_refresh" to forceRefresh
|
||||||
|
)
|
||||||
}) {
|
}) {
|
||||||
Timber.i("Loading grade stats result: An exception occurred")
|
Timber.i("Loading grade stats result: An exception occurred")
|
||||||
errorHandler.dispatch(it)
|
errorHandler.dispatch(it)
|
||||||
|
@ -49,7 +49,12 @@ class GradeSummaryPresenter @Inject constructor(
|
|||||||
showErrorView(false)
|
showErrorView(false)
|
||||||
updateData(it)
|
updateData(it)
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_grade_summary", "items" to it.size, "force_refresh" to forceRefresh)
|
analytics.logEvent(
|
||||||
|
"load_data",
|
||||||
|
"type" to "grade_summary",
|
||||||
|
"items" to it.size,
|
||||||
|
"force_refresh" to forceRefresh
|
||||||
|
)
|
||||||
}) {
|
}) {
|
||||||
Timber.i("Loading grade summary result: An exception occurred")
|
Timber.i("Loading grade summary result: An exception occurred")
|
||||||
errorHandler.dispatch(it)
|
errorHandler.dispatch(it)
|
||||||
@ -103,14 +108,18 @@ class GradeSummaryPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createGradeSummaryItems(items: List<GradeDetailsWithAverage>): List<GradeSummary> {
|
private fun createGradeSummaryItems(items: List<GradeDetailsWithAverage>): List<GradeSummary> {
|
||||||
return items.map {
|
return items
|
||||||
it.summary.copy(average = it.average)
|
.filter { !checkEmpty(it) }
|
||||||
}
|
.sortedBy { it.subject }
|
||||||
|
.map { it.summary.copy(average = it.average) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkEmpty(gradeSummary: GradeSummary, averages: List<Triple<String, Double, String>>): Boolean {
|
private fun checkEmpty(gradeSummary: GradeDetailsWithAverage): Boolean {
|
||||||
return gradeSummary.run {
|
return gradeSummary.run {
|
||||||
finalGrade.isBlank() && predictedGrade.isBlank() && averages.singleOrNull { it.first == subject } == null
|
summary.finalGrade.isBlank()
|
||||||
|
&& summary.predictedGrade.isBlank()
|
||||||
|
&& average == .0
|
||||||
|
&& points.isBlank()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import io.github.wulkanowy.ui.base.BasePresenter
|
|||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
|
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
|
||||||
import io.github.wulkanowy.utils.isHolidays
|
import io.github.wulkanowy.utils.isHolidays
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
@ -124,7 +124,12 @@ class HomeworkPresenter @Inject constructor(
|
|||||||
showErrorView(false)
|
showErrorView(false)
|
||||||
showContent(it.isNotEmpty())
|
showContent(it.isNotEmpty())
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_homework", "items" to it.size, "force_refresh" to forceRefresh)
|
analytics.logEvent(
|
||||||
|
"load_data",
|
||||||
|
"type" to "homework",
|
||||||
|
"items" to it.size,
|
||||||
|
"force_refresh" to forceRefresh
|
||||||
|
)
|
||||||
}) {
|
}) {
|
||||||
Timber.i("Loading homework result: An exception occurred")
|
Timber.i("Loading homework result: An exception occurred")
|
||||||
|
|
||||||
@ -170,7 +175,7 @@ class HomeworkPresenter @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.sunday.toFormattedString("dd.MM"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,10 @@ import javax.inject.Inject
|
|||||||
class LoginRecoverFragment :
|
class LoginRecoverFragment :
|
||||||
BaseFragment<FragmentLoginRecoverBinding>(R.layout.fragment_login_recover), LoginRecoverView {
|
BaseFragment<FragmentLoginRecoverBinding>(R.layout.fragment_login_recover), LoginRecoverView {
|
||||||
|
|
||||||
|
private var _binding: FragmentLoginRecoverBinding? = null
|
||||||
|
|
||||||
|
private val bindingLocal: FragmentLoginRecoverBinding get() = _binding!!
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: LoginRecoverPresenter
|
lateinit var presenter: LoginRecoverPresenter
|
||||||
|
|
||||||
@ -36,13 +40,13 @@ class LoginRecoverFragment :
|
|||||||
private lateinit var hostSymbols: Array<String>
|
private lateinit var hostSymbols: Array<String>
|
||||||
|
|
||||||
override val recoverHostValue: String
|
override val recoverHostValue: String
|
||||||
get() = hostValues.getOrNull(hostKeys.indexOf(binding.loginRecoverHost.text.toString())).orEmpty()
|
get() = hostValues.getOrNull(hostKeys.indexOf(bindingLocal.loginRecoverHost.text.toString())).orEmpty()
|
||||||
|
|
||||||
override val formHostSymbol: String
|
override val formHostSymbol: String
|
||||||
get() = hostSymbols.getOrNull(hostKeys.indexOf(binding.loginRecoverHost.text.toString())).orEmpty()
|
get() = hostSymbols.getOrNull(hostKeys.indexOf(bindingLocal.loginRecoverHost.text.toString())).orEmpty()
|
||||||
|
|
||||||
override val recoverNameValue: String
|
override val recoverNameValue: String
|
||||||
get() = binding.loginRecoverName.text.toString().trim()
|
get() = bindingLocal.loginRecoverName.text.toString().trim()
|
||||||
|
|
||||||
override val emailHintString: String
|
override val emailHintString: String
|
||||||
get() = getString(R.string.login_email_hint)
|
get() = getString(R.string.login_email_hint)
|
||||||
@ -55,7 +59,7 @@ class LoginRecoverFragment :
|
|||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
binding = FragmentLoginRecoverBinding.bind(view)
|
_binding = FragmentLoginRecoverBinding.bind(view)
|
||||||
presenter.onAttachView(this)
|
presenter.onAttachView(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +68,7 @@ class LoginRecoverFragment :
|
|||||||
hostValues = resources.getStringArray(R.array.hosts_values)
|
hostValues = resources.getStringArray(R.array.hosts_values)
|
||||||
hostSymbols = resources.getStringArray(R.array.hosts_symbols)
|
hostSymbols = resources.getStringArray(R.array.hosts_symbols)
|
||||||
|
|
||||||
with(binding) {
|
with(bindingLocal) {
|
||||||
loginRecoverWebView.setBackgroundColor(Color.TRANSPARENT)
|
loginRecoverWebView.setBackgroundColor(Color.TRANSPARENT)
|
||||||
loginRecoverName.doOnTextChanged { _, _, _, _ -> presenter.onNameTextChanged() }
|
loginRecoverName.doOnTextChanged { _, _, _, _ -> presenter.onNameTextChanged() }
|
||||||
loginRecoverHost.setOnItemClickListener { _, _, _, _ -> presenter.onHostSelected() }
|
loginRecoverHost.setOnItemClickListener { _, _, _, _ -> presenter.onHostSelected() }
|
||||||
@ -74,69 +78,69 @@ class LoginRecoverFragment :
|
|||||||
loginRecoverLogin.setOnClickListener { (activity as LoginActivity).switchView(0) }
|
loginRecoverLogin.setOnClickListener { (activity as LoginActivity).switchView(0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
with(binding.loginRecoverHost) {
|
with(bindingLocal.loginRecoverHost) {
|
||||||
setText(hostKeys.getOrNull(0).orEmpty())
|
setText(hostKeys.getOrNull(0).orEmpty())
|
||||||
setAdapter(LoginSymbolAdapter(context, R.layout.support_simple_spinner_dropdown_item, hostKeys))
|
setAdapter(LoginSymbolAdapter(context, R.layout.support_simple_spinner_dropdown_item, hostKeys))
|
||||||
setOnClickListener { if (binding.loginRecoverFormContainer.visibility == GONE) dismissDropDown() }
|
setOnClickListener { if (bindingLocal.loginRecoverFormContainer.visibility == GONE) dismissDropDown() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setDefaultCredentials(username: String) {
|
override fun setDefaultCredentials(username: String) {
|
||||||
binding.loginRecoverName.setText(username)
|
bindingLocal.loginRecoverName.setText(username)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setErrorNameRequired() {
|
override fun setErrorNameRequired() {
|
||||||
with(binding.loginRecoverNameLayout) {
|
with(bindingLocal.loginRecoverNameLayout) {
|
||||||
requestFocus()
|
requestFocus()
|
||||||
error = getString(R.string.login_field_required)
|
error = getString(R.string.login_field_required)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setUsernameHint(hint: String) {
|
override fun setUsernameHint(hint: String) {
|
||||||
binding.loginRecoverNameLayout.hint = hint
|
bindingLocal.loginRecoverNameLayout.hint = hint
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setUsernameError(message: String) {
|
override fun setUsernameError(message: String) {
|
||||||
with(binding.loginRecoverNameLayout) {
|
with(bindingLocal.loginRecoverNameLayout) {
|
||||||
requestFocus()
|
requestFocus()
|
||||||
error = message
|
error = message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun clearUsernameError() {
|
override fun clearUsernameError() {
|
||||||
binding.loginRecoverNameLayout.error = null
|
bindingLocal.loginRecoverNameLayout.error = null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showProgress(show: Boolean) {
|
override fun showProgress(show: Boolean) {
|
||||||
binding.loginRecoverProgress.visibility = if (show) VISIBLE else GONE
|
bindingLocal.loginRecoverProgress.visibility = if (show) VISIBLE else GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showRecoverForm(show: Boolean) {
|
override fun showRecoverForm(show: Boolean) {
|
||||||
binding.loginRecoverFormContainer.visibility = if (show) VISIBLE else GONE
|
bindingLocal.loginRecoverFormContainer.visibility = if (show) VISIBLE else GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showCaptcha(show: Boolean) {
|
override fun showCaptcha(show: Boolean) {
|
||||||
binding.loginRecoverCaptchaContainer.visibility = if (show) VISIBLE else GONE
|
bindingLocal.loginRecoverCaptchaContainer.visibility = if (show) VISIBLE else GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showErrorView(show: Boolean) {
|
override fun showErrorView(show: Boolean) {
|
||||||
binding.loginRecoverError.visibility = if (show) VISIBLE else GONE
|
bindingLocal.loginRecoverError.visibility = if (show) VISIBLE else GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setErrorDetails(message: String) {
|
override fun setErrorDetails(message: String) {
|
||||||
binding.loginRecoverErrorMessage.text = message
|
bindingLocal.loginRecoverErrorMessage.text = message
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showSuccessView(show: Boolean) {
|
override fun showSuccessView(show: Boolean) {
|
||||||
binding.loginRecoverSuccess.visibility = if (show) VISIBLE else GONE
|
bindingLocal.loginRecoverSuccess.visibility = if (show) VISIBLE else GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setSuccessTitle(title: String) {
|
override fun setSuccessTitle(title: String) {
|
||||||
binding.loginRecoverSuccessTitle.text = title
|
bindingLocal.loginRecoverSuccessTitle.text = title
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setSuccessMessage(message: String) {
|
override fun setSuccessMessage(message: String) {
|
||||||
binding.loginRecoverSuccessMessage.text = message
|
bindingLocal.loginRecoverSuccessMessage.text = message
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showSoftKeyboard() {
|
override fun showSoftKeyboard() {
|
||||||
@ -157,7 +161,7 @@ class LoginRecoverFragment :
|
|||||||
callback:e =>Android.captchaCallback(e)})</script>
|
callback:e =>Android.captchaCallback(e)})</script>
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
with(binding.loginRecoverWebView) {
|
with(bindingLocal.loginRecoverWebView) {
|
||||||
settings.javaScriptEnabled = true
|
settings.javaScriptEnabled = true
|
||||||
webViewClient = object : WebViewClient() {
|
webViewClient = object : WebViewClient() {
|
||||||
private var recoverWebViewSuccess: Boolean = true
|
private var recoverWebViewSuccess: Boolean = true
|
||||||
@ -197,6 +201,8 @@ class LoginRecoverFragment :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
bindingLocal.loginRecoverWebView.destroy()
|
||||||
|
_binding = null
|
||||||
presenter.onDetachView()
|
presenter.onDetachView()
|
||||||
|
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
|
@ -12,7 +12,13 @@ import javax.inject.Inject
|
|||||||
class LoginStudentSelectAdapter @Inject constructor() :
|
class LoginStudentSelectAdapter @Inject constructor() :
|
||||||
RecyclerView.Adapter<LoginStudentSelectAdapter.ItemViewHolder>() {
|
RecyclerView.Adapter<LoginStudentSelectAdapter.ItemViewHolder>() {
|
||||||
|
|
||||||
|
private val checkedList = mutableMapOf<Int, Boolean>()
|
||||||
|
|
||||||
var items = emptyList<Pair<Student, Boolean>>()
|
var items = emptyList<Pair<Student, Boolean>>()
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
checkedList.clear()
|
||||||
|
}
|
||||||
|
|
||||||
var onClickListener: (Student, alreadySaved: Boolean) -> Unit = { _, _ -> }
|
var onClickListener: (Student, alreadySaved: Boolean) -> Unit = { _, _ -> }
|
||||||
|
|
||||||
@ -31,15 +37,21 @@ class LoginStudentSelectAdapter @Inject constructor() :
|
|||||||
loginItemSchool.text = student.schoolName
|
loginItemSchool.text = student.schoolName
|
||||||
loginItemName.isEnabled = !alreadySaved
|
loginItemName.isEnabled = !alreadySaved
|
||||||
loginItemSchool.isEnabled = !alreadySaved
|
loginItemSchool.isEnabled = !alreadySaved
|
||||||
loginItemCheck.isEnabled = !alreadySaved
|
|
||||||
loginItemSignedIn.visibility = if (alreadySaved) View.VISIBLE else View.GONE
|
loginItemSignedIn.visibility = if (alreadySaved) View.VISIBLE else View.GONE
|
||||||
|
|
||||||
|
with(loginItemCheck) {
|
||||||
|
isEnabled = !alreadySaved
|
||||||
|
keyListener = null
|
||||||
|
isChecked = checkedList[position] ?: false
|
||||||
|
}
|
||||||
|
|
||||||
root.setOnClickListener {
|
root.setOnClickListener {
|
||||||
onClickListener(student, alreadySaved)
|
onClickListener(student, alreadySaved)
|
||||||
|
|
||||||
with(loginItemCheck) {
|
with(loginItemCheck) {
|
||||||
if (isEnabled) {
|
if (isEnabled) {
|
||||||
isChecked = !isChecked
|
isChecked = !isChecked
|
||||||
|
checkedList[position] = isChecked
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ class LoginStudentSelectPresenter @Inject constructor(
|
|||||||
|
|
||||||
var students = emptyList<Student>()
|
var students = emptyList<Student>()
|
||||||
|
|
||||||
private var selectedStudents = mutableListOf<Student>()
|
private val selectedStudents = mutableListOf<Student>()
|
||||||
|
|
||||||
fun onAttachView(view: LoginStudentSelectView, students: Serializable?) {
|
fun onAttachView(view: LoginStudentSelectView, students: Serializable?) {
|
||||||
super.onAttachView(view)
|
super.onAttachView(view)
|
||||||
@ -69,6 +69,7 @@ class LoginStudentSelectPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData(students: List<Student>) {
|
private fun loadData(students: List<Student>) {
|
||||||
|
resetSelectedState()
|
||||||
this.students = students
|
this.students = students
|
||||||
disposable.add(studentRepository.getSavedStudents()
|
disposable.add(studentRepository.getSavedStudents()
|
||||||
.map { savedStudents ->
|
.map { savedStudents ->
|
||||||
@ -88,6 +89,11 @@ class LoginStudentSelectPresenter @Inject constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun resetSelectedState() {
|
||||||
|
selectedStudents.clear()
|
||||||
|
view?.enableSignIn(false)
|
||||||
|
}
|
||||||
|
|
||||||
private fun registerStudents(students: List<Student>) {
|
private fun registerStudents(students: List<Student>) {
|
||||||
disposable.add(studentRepository.saveStudents(students)
|
disposable.add(studentRepository.saveStudents(students)
|
||||||
.map { students.first().apply { id = it.first() } }
|
.map { students.first().apply { id = it.first() } }
|
||||||
|
@ -54,7 +54,12 @@ class LuckyNumberPresenter @Inject constructor(
|
|||||||
showEmpty(false)
|
showEmpty(false)
|
||||||
showErrorView(false)
|
showErrorView(false)
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_lucky_number", "lucky_number" to it.luckyNumber, "force_refresh" to forceRefresh)
|
analytics.logEvent(
|
||||||
|
"load_item",
|
||||||
|
"type" to "lucky_number",
|
||||||
|
"number" to it.luckyNumber,
|
||||||
|
"force_refresh" to forceRefresh
|
||||||
|
)
|
||||||
}, {
|
}, {
|
||||||
Timber.i("Loading lucky number result: An exception occurred")
|
Timber.i("Loading lucky number result: An exception occurred")
|
||||||
errorHandler.dispatch(it)
|
errorHandler.dispatch(it)
|
||||||
|
@ -31,6 +31,7 @@ import io.github.wulkanowy.ui.modules.message.MessageFragment
|
|||||||
import io.github.wulkanowy.ui.modules.more.MoreFragment
|
import io.github.wulkanowy.ui.modules.more.MoreFragment
|
||||||
import io.github.wulkanowy.ui.modules.note.NoteFragment
|
import io.github.wulkanowy.ui.modules.note.NoteFragment
|
||||||
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
|
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
|
||||||
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.dpToPx
|
import io.github.wulkanowy.utils.dpToPx
|
||||||
import io.github.wulkanowy.utils.getThemeAttrColor
|
import io.github.wulkanowy.utils.getThemeAttrColor
|
||||||
import io.github.wulkanowy.utils.safelyPopFragments
|
import io.github.wulkanowy.utils.safelyPopFragments
|
||||||
@ -46,6 +47,9 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var navController: FragNavController
|
lateinit var navController: FragNavController
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var analytics: FirebaseAnalyticsHelper
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var overlayProvider: Lazy<ElevationOverlayProvider>
|
lateinit var overlayProvider: Lazy<ElevationOverlayProvider>
|
||||||
|
|
||||||
@ -136,6 +140,10 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun setCurrentScreen(name: String?) {
|
||||||
|
analytics.setCurrentScreen(this, name)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
|
||||||
return if (item?.itemId == R.id.mainMenuAccount) presenter.onAccountManagerSelected()
|
return if (item?.itemId == R.id.mainMenuAccount) presenter.onAccountManagerSelected()
|
||||||
else false
|
else false
|
||||||
|
@ -37,8 +37,9 @@ class MainPresenter @Inject constructor(
|
|||||||
analytics.logEvent("app_open", "destination" to initMenu?.name)
|
analytics.logEvent("app_open", "destination" to initMenu?.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onViewChange(section: MainView.Section?) {
|
fun onViewChange(section: MainView.Section?, name: String?) {
|
||||||
view?.apply {
|
view?.apply {
|
||||||
|
setCurrentScreen(name)
|
||||||
showActionBarElevation(section != GRADE && section != MESSAGE && section != SCHOOL)
|
showActionBarElevation(section != GRADE && section != MESSAGE && section != SCHOOL)
|
||||||
currentViewTitle?.let { setViewTitle(it) }
|
currentViewTitle?.let { setViewTitle(it) }
|
||||||
currentViewSubtitle?.let { setViewSubTitle(it.ifBlank { null }) }
|
currentViewSubtitle?.let { setViewSubTitle(it.ifBlank { null }) }
|
||||||
|
@ -24,6 +24,8 @@ interface MainView : BaseView {
|
|||||||
|
|
||||||
fun showAccountPicker()
|
fun showAccountPicker()
|
||||||
|
|
||||||
|
fun setCurrentScreen(name: String?)
|
||||||
|
|
||||||
fun showActionBarElevation(show: Boolean)
|
fun showActionBarElevation(show: Boolean)
|
||||||
|
|
||||||
fun notifyMenuViewReselected()
|
fun notifyMenuViewReselected()
|
||||||
|
@ -60,7 +60,11 @@ class MessagePreviewPresenter @Inject constructor(
|
|||||||
setMessageWithAttachment(message)
|
setMessageWithAttachment(message)
|
||||||
initOptions()
|
initOptions()
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_message_preview", "length" to message.message.content.length)
|
analytics.logEvent(
|
||||||
|
"load_item",
|
||||||
|
"type" to "message_preview",
|
||||||
|
"length" to message.message.content.length
|
||||||
|
)
|
||||||
}) {
|
}) {
|
||||||
Timber.i("Loading message ${message.messageId} preview result: An exception occurred ")
|
Timber.i("Loading message ${message.messageId} preview result: An exception occurred ")
|
||||||
retryCallback = { onMessageLoadRetry(message) }
|
retryCallback = { onMessageLoadRetry(message) }
|
||||||
|
@ -5,6 +5,7 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.recyclerview.widget.RecyclerView.NO_POSITION
|
||||||
import androidx.recyclerview.widget.SortedList
|
import androidx.recyclerview.widget.SortedList
|
||||||
import androidx.recyclerview.widget.SortedListAdapterCallback
|
import androidx.recyclerview.widget.SortedListAdapterCallback
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
@ -77,7 +78,9 @@ class MessageTabAdapter @Inject constructor() :
|
|||||||
}
|
}
|
||||||
messageItemAttachmentIcon.visibility = if (item.hasAttachments) View.VISIBLE else View.GONE
|
messageItemAttachmentIcon.visibility = if (item.hasAttachments) View.VISIBLE else View.GONE
|
||||||
|
|
||||||
root.setOnClickListener { onClickListener(item, position) }
|
root.setOnClickListener {
|
||||||
|
holder.adapterPosition.let { if (it != NO_POSITION) onClickListener(item, it) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ class MessageTabPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onMessageItemSelected(message: Message, position: Int) {
|
fun onMessageItemSelected(message: Message, position: Int) {
|
||||||
Timber.i("Select message ${message.id} item")
|
Timber.i("Select message ${message.id} item (position: $position)")
|
||||||
view?.run {
|
view?.run {
|
||||||
openMessage(message)
|
openMessage(message)
|
||||||
if (message.unread) {
|
if (message.unread) {
|
||||||
@ -97,7 +97,12 @@ class MessageTabPresenter @Inject constructor(
|
|||||||
Timber.i("Loading $folder message result: Success")
|
Timber.i("Loading $folder message result: Success")
|
||||||
messages = it
|
messages = it
|
||||||
onSearchQueryTextChange(lastSearchQuery)
|
onSearchQueryTextChange(lastSearchQuery)
|
||||||
analytics.logEvent("load_messages", "items" to it.size, "folder" to folder.name)
|
analytics.logEvent(
|
||||||
|
"load_data",
|
||||||
|
"type" to "messages",
|
||||||
|
"items" to it.size,
|
||||||
|
"folder" to folder.name
|
||||||
|
)
|
||||||
}) {
|
}) {
|
||||||
Timber.i("Loading $folder message result: An exception occurred")
|
Timber.i("Loading $folder message result: An exception occurred")
|
||||||
errorHandler.dispatch(it)
|
errorHandler.dispatch(it)
|
||||||
@ -132,6 +137,8 @@ class MessageTabPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timber.d("Applying filter. Full list: ${messages.size}, filtered: ${filteredList.size}")
|
||||||
|
|
||||||
updateData(filteredList)
|
updateData(filteredList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +70,12 @@ class MobileDevicePresenter @Inject constructor(
|
|||||||
showEmpty(it.isEmpty())
|
showEmpty(it.isEmpty())
|
||||||
showErrorView(false)
|
showErrorView(false)
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_devices", "items" to it.size, "force_refresh" to forceRefresh)
|
analytics.logEvent(
|
||||||
|
"load_data",
|
||||||
|
"type" to "devices",
|
||||||
|
"items" to it.size,
|
||||||
|
"force_refresh" to forceRefresh
|
||||||
|
)
|
||||||
}) {
|
}) {
|
||||||
Timber.i("Loading mobile devices result: An exception occurred")
|
Timber.i("Loading mobile devices result: An exception occurred")
|
||||||
errorHandler.dispatch(it)
|
errorHandler.dispatch(it)
|
||||||
|
@ -69,7 +69,12 @@ class NotePresenter @Inject constructor(
|
|||||||
showErrorView(false)
|
showErrorView(false)
|
||||||
showContent(it.isNotEmpty())
|
showContent(it.isNotEmpty())
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_note", "items" to it.size, "force_refresh" to forceRefresh)
|
analytics.logEvent(
|
||||||
|
"load_data",
|
||||||
|
"type" to "note",
|
||||||
|
"items" to it.size,
|
||||||
|
"force_refresh" to forceRefresh
|
||||||
|
)
|
||||||
}, {
|
}, {
|
||||||
Timber.i("Loading note result: An exception occurred")
|
Timber.i("Loading note result: An exception occurred")
|
||||||
errorHandler.dispatch(it)
|
errorHandler.dispatch(it)
|
||||||
|
@ -88,7 +88,11 @@ class SchoolPresenter @Inject constructor(
|
|||||||
showEmpty(false)
|
showEmpty(false)
|
||||||
showErrorView(false)
|
showErrorView(false)
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_school", "force_refresh" to forceRefresh)
|
analytics.logEvent(
|
||||||
|
"load_item",
|
||||||
|
"type" to "school",
|
||||||
|
"force_refresh" to forceRefresh
|
||||||
|
)
|
||||||
}, {
|
}, {
|
||||||
Timber.i("Loading school result: An exception occurred")
|
Timber.i("Loading school result: An exception occurred")
|
||||||
errorHandler.dispatch(it)
|
errorHandler.dispatch(it)
|
||||||
|
@ -75,7 +75,12 @@ class TeacherPresenter @Inject constructor(
|
|||||||
showEmpty(it.isEmpty())
|
showEmpty(it.isEmpty())
|
||||||
showErrorView(false)
|
showErrorView(false)
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_teachers", "items" to it.size, "force_refresh" to forceRefresh)
|
analytics.logEvent(
|
||||||
|
"load_data",
|
||||||
|
"type" to "teachers",
|
||||||
|
"items" to it.size,
|
||||||
|
"force_refresh" to forceRefresh
|
||||||
|
)
|
||||||
}) {
|
}) {
|
||||||
Timber.i("Loading teachers result: An exception occurred")
|
Timber.i("Loading teachers result: An exception occurred")
|
||||||
errorHandler.dispatch(it)
|
errorHandler.dispatch(it)
|
||||||
|
@ -7,6 +7,7 @@ import androidx.appcompat.app.AlertDialog
|
|||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import com.thelittlefireman.appkillermanager.AppKillerManager
|
import com.thelittlefireman.appkillermanager.AppKillerManager
|
||||||
|
import com.thelittlefireman.appkillermanager.exceptions.NoActionFoundException
|
||||||
import com.yariksoffice.lingver.Lingver
|
import com.yariksoffice.lingver.Lingver
|
||||||
import dagger.android.support.AndroidSupportInjection
|
import dagger.android.support.AndroidSupportInjection
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
@ -14,6 +15,7 @@ import io.github.wulkanowy.ui.base.BaseActivity
|
|||||||
import io.github.wulkanowy.ui.base.ErrorDialog
|
import io.github.wulkanowy.ui.base.ErrorDialog
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import io.github.wulkanowy.utils.AppInfo
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
|
import io.github.wulkanowy.utils.openInternetBrowser
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class SettingsFragment : PreferenceFragmentCompat(),
|
class SettingsFragment : PreferenceFragmentCompat(),
|
||||||
@ -133,9 +135,13 @@ class SettingsFragment : PreferenceFragmentCompat(),
|
|||||||
.setMessage(R.string.pref_notify_fix_sync_issues_message)
|
.setMessage(R.string.pref_notify_fix_sync_issues_message)
|
||||||
.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
||||||
.setPositiveButton(R.string.pref_notify_fix_sync_issues_settings_button) { _, _ ->
|
.setPositiveButton(R.string.pref_notify_fix_sync_issues_settings_button) { _, _ ->
|
||||||
AppKillerManager.doActionPowerSaving(requireContext())
|
try {
|
||||||
AppKillerManager.doActionAutoStart(requireContext())
|
AppKillerManager.doActionPowerSaving(requireContext())
|
||||||
AppKillerManager.doActionNotification(requireContext())
|
AppKillerManager.doActionAutoStart(requireContext())
|
||||||
|
AppKillerManager.doActionNotification(requireContext())
|
||||||
|
} catch (e: NoActionFoundException) {
|
||||||
|
requireContext().openInternetBrowser("https://dontkillmyapp.com/${AppKillerManager.getDevice()?.manufacturer}", ::showMessage)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
@ -132,41 +132,46 @@ class TimetableAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateTimeLeft(binding: ItemTimetableBinding, lesson: Timetable, position: Int) {
|
private fun updateTimeLeft(binding: ItemTimetableBinding, lesson: Timetable, position: Int) {
|
||||||
|
val isShowTimeUntil = lesson.isShowTimeUntil(getPreviousLesson(position))
|
||||||
|
val until = lesson.until
|
||||||
|
val left = lesson.left
|
||||||
|
val isJustFinished = lesson.isJustFinished
|
||||||
|
|
||||||
with(binding) {
|
with(binding) {
|
||||||
when {
|
when {
|
||||||
// before lesson
|
// before lesson
|
||||||
lesson.isShowTimeUntil(getPreviousLesson(position)) -> {
|
isShowTimeUntil -> {
|
||||||
Timber.d("Show time until lesson: $position")
|
Timber.d("Show time until lesson: $position")
|
||||||
timetableItemTimeLeft.visibility = GONE
|
timetableItemTimeLeft.visibility = GONE
|
||||||
with(timetableItemTimeUntil) {
|
with(timetableItemTimeUntil) {
|
||||||
visibility = VISIBLE
|
visibility = VISIBLE
|
||||||
text = context.getString(R.string.timetable_time_until,
|
text = context.getString(R.string.timetable_time_until,
|
||||||
if (lesson.until.seconds <= 60) {
|
if (until.seconds <= 60) {
|
||||||
context.getString(R.string.timetable_seconds, lesson.until.seconds.toString(10))
|
context.getString(R.string.timetable_seconds, until.seconds.toString(10))
|
||||||
} else {
|
} else {
|
||||||
context.getString(R.string.timetable_minutes, lesson.until.toMinutes().toString(10))
|
context.getString(R.string.timetable_minutes, until.toMinutes().toString(10))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// after lesson start
|
// after lesson start
|
||||||
lesson.left != null -> {
|
left != null -> {
|
||||||
Timber.d("Show time left lesson: $position")
|
Timber.d("Show time left lesson: $position")
|
||||||
timetableItemTimeUntil.visibility = GONE
|
timetableItemTimeUntil.visibility = GONE
|
||||||
with(timetableItemTimeLeft) {
|
with(timetableItemTimeLeft) {
|
||||||
visibility = VISIBLE
|
visibility = VISIBLE
|
||||||
text = context.getString(
|
text = context.getString(
|
||||||
R.string.timetable_time_left,
|
R.string.timetable_time_left,
|
||||||
if (lesson.left!!.seconds < 60) {
|
if (left.seconds < 60) {
|
||||||
context.getString(R.string.timetable_seconds, lesson.left?.seconds?.toString(10))
|
context.getString(R.string.timetable_seconds, left.seconds.toString(10))
|
||||||
} else {
|
} else {
|
||||||
context.getString(R.string.timetable_minutes, lesson.left?.toMinutes()?.toString(10))
|
context.getString(R.string.timetable_minutes, left.toMinutes().toString(10))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// right after lesson finish
|
// right after lesson finish
|
||||||
lesson.isJustFinished -> {
|
isJustFinished -> {
|
||||||
Timber.d("Show just finished lesson: $position")
|
Timber.d("Show just finished lesson: $position")
|
||||||
timetableItemTimeUntil.visibility = GONE
|
timetableItemTimeUntil.visibility = GONE
|
||||||
timetableItemTimeLeft.visibility = VISIBLE
|
timetableItemTimeLeft.visibility = VISIBLE
|
||||||
|
@ -154,7 +154,12 @@ class TimetablePresenter @Inject constructor(
|
|||||||
showErrorView(false)
|
showErrorView(false)
|
||||||
showContent(it.isNotEmpty())
|
showContent(it.isNotEmpty())
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_timetable", "items" to it.size, "force_refresh" to forceRefresh)
|
analytics.logEvent(
|
||||||
|
"load_data",
|
||||||
|
"type" to "timetable",
|
||||||
|
"items" to it.size,
|
||||||
|
"force_refresh" to forceRefresh
|
||||||
|
)
|
||||||
}) {
|
}) {
|
||||||
Timber.i("Loading timetable result: An exception occurred")
|
Timber.i("Loading timetable result: An exception occurred")
|
||||||
errorHandler.dispatch(it)
|
errorHandler.dispatch(it)
|
||||||
|
@ -43,6 +43,7 @@ class CompletedLessonsPresenter @Inject constructor(
|
|||||||
completedLessonsErrorHandler.showErrorMessage = ::showErrorViewOnError
|
completedLessonsErrorHandler.showErrorMessage = ::showErrorViewOnError
|
||||||
completedLessonsErrorHandler.onFeatureDisabled = {
|
completedLessonsErrorHandler.onFeatureDisabled = {
|
||||||
this.view?.showFeatureDisabled()
|
this.view?.showFeatureDisabled()
|
||||||
|
this.view?.showEmpty(true);
|
||||||
Timber.i("Completed lessons feature disabled by school")
|
Timber.i("Completed lessons feature disabled by school")
|
||||||
}
|
}
|
||||||
loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
|
loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
|
||||||
@ -134,7 +135,12 @@ class CompletedLessonsPresenter @Inject constructor(
|
|||||||
showErrorView(false)
|
showErrorView(false)
|
||||||
showContent(it.isNotEmpty())
|
showContent(it.isNotEmpty())
|
||||||
}
|
}
|
||||||
analytics.logEvent("load_completed_lessons", "items" to it.size, "force_refresh" to forceRefresh)
|
analytics.logEvent(
|
||||||
|
"load_data",
|
||||||
|
"type" to "completed_lessons",
|
||||||
|
"items" to it.size,
|
||||||
|
"force_refresh" to forceRefresh
|
||||||
|
)
|
||||||
}) {
|
}) {
|
||||||
Timber.i("Loading completed lessons result: An exception occurred")
|
Timber.i("Loading completed lessons result: An exception occurred")
|
||||||
completedLessonsErrorHandler.dispatch(it)
|
completedLessonsErrorHandler.dispatch(it)
|
||||||
|
@ -10,7 +10,7 @@ import androidx.annotation.ColorRes
|
|||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.graphics.ColorUtils
|
import androidx.core.graphics.ColorUtils
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.BuildConfig.APPLICATION_ID
|
||||||
|
|
||||||
@ColorInt
|
@ColorInt
|
||||||
fun Context.getThemeAttrColor(@AttrRes colorAttr: Int): Int {
|
fun Context.getThemeAttrColor(@AttrRes colorAttr: Int): Int {
|
||||||
@ -39,6 +39,12 @@ fun Context.openInternetBrowser(uri: String, onActivityNotFound: (uri: String) -
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Context.openAppInMarket(onActivityNotFound: (uri: String) -> Unit) {
|
||||||
|
openInternetBrowser("market://details?id=${APPLICATION_ID}") {
|
||||||
|
openInternetBrowser("https://github.com/wulkanowy/wulkanowy/releases", onActivityNotFound)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun Context.openEmailClient(chooserTitle: String, email: String, subject: String, body: String, onActivityNotFound: () -> Unit = {}) {
|
fun Context.openEmailClient(chooserTitle: String, email: String, subject: String, body: String, onActivityNotFound: () -> Unit = {}) {
|
||||||
val intent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:")).apply {
|
val intent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:")).apply {
|
||||||
putExtra(Intent.EXTRA_EMAIL, arrayOf(email))
|
putExtra(Intent.EXTRA_EMAIL, arrayOf(email))
|
||||||
|
@ -4,14 +4,14 @@ import androidx.fragment.app.Fragment
|
|||||||
import com.ncapdevi.fragnav.FragNavController
|
import com.ncapdevi.fragnav.FragNavController
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
|
|
||||||
inline fun FragNavController.setOnViewChangeListener(crossinline listener: (section: MainView.Section?) -> Unit) {
|
inline fun FragNavController.setOnViewChangeListener(crossinline listener: (section: MainView.Section?, name: String?) -> Unit) {
|
||||||
transactionListener = object : FragNavController.TransactionListener {
|
transactionListener = object : FragNavController.TransactionListener {
|
||||||
override fun onFragmentTransaction(fragment: Fragment?, transactionType: FragNavController.TransactionType) {
|
override fun onFragmentTransaction(fragment: Fragment?, transactionType: FragNavController.TransactionType) {
|
||||||
listener(fragment?.toSection())
|
listener(fragment?.toSection(), fragment?.let { it::class.java.simpleName })
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTabTransaction(fragment: Fragment?, index: Int) {
|
override fun onTabTransaction(fragment: Fragment?, index: Int) {
|
||||||
listener(fragment?.toSection())
|
listener(fragment?.toSection(), fragment?.let { it::class.java.simpleName })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ class SchooldaysRangeLimiter : DateRangeLimiter {
|
|||||||
override fun isOutOfRange(year: Int, month: Int, day: Int): Boolean {
|
override fun isOutOfRange(year: Int, month: Int, day: Int): Boolean {
|
||||||
val date = LocalDate.of(year, month + 1, day)
|
val date = LocalDate.of(year, month + 1, day)
|
||||||
val dayOfWeek = date.dayOfWeek
|
val dayOfWeek = date.dayOfWeek
|
||||||
return dayOfWeek == DayOfWeek.SUNDAY || dayOfWeek == DayOfWeek.SATURDAY || date.isHolidays
|
return dayOfWeek == DayOfWeek.SUNDAY || date.isHolidays
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getStartDate(): Calendar {
|
override fun getStartDate(): Calendar {
|
||||||
|
@ -92,8 +92,8 @@ inline val LocalDate.weekDayName: String
|
|||||||
inline val LocalDate.monday: LocalDate
|
inline val LocalDate.monday: LocalDate
|
||||||
get() = with(MONDAY)
|
get() = with(MONDAY)
|
||||||
|
|
||||||
inline val LocalDate.friday: LocalDate
|
inline val LocalDate.sunday: LocalDate
|
||||||
get() = with(FRIDAY)
|
get() = with(SUNDAY)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [Dz.U. 2016 poz. 1335](http://prawo.sejm.gov.pl/isap.nsf/DocDetails.xsp?id=WDU20160001335)
|
* [Dz.U. 2016 poz. 1335](http://prawo.sejm.gov.pl/isap.nsf/DocDetails.xsp?id=WDU20160001335)
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
Wersja 0.18.0
|
Wersja 0.18.2
|
||||||
- naprawiliśmy odświeżanie zadań domowych
|
- naprawiliśmy zaznaczanie uczniów przy logowaniu
|
||||||
- naprawiliśmy powiadomienia na androidzie 8.0
|
- naprawiliśmy odświeżanie planu lekcji na samsungach
|
||||||
- oceny powinny się teraz odświeżać trochę szybciej
|
- naprawiliśmy wysyłanie wiadomości
|
||||||
- dodaliśmy tryb pełnoekranowy w zadaniach
|
- poprawiliśmy oznaczanie nowych wiadomości jako przeczytanych
|
||||||
- dodaliśmy wyszukiwanie w wiadomościach
|
- w podsumowaniu ocen nie będą się już pokazywać „puste” przedmioty
|
||||||
- dodaliśmy opcje oznaczania bieżącej lekcji na planie/w powiadomieniu (domyślnie wyłączone)
|
- w polu pisania wiadomości pierwsza litera w zdaniu będzie teraz domyślnie duża
|
||||||
- dodaliśmy testową opcję naprawy powiadomień na np. Huawei, Xiaomi (znajdziesz ją w ustawieniach)
|
|
||||||
|
|
||||||
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
||||||
|
@ -148,7 +148,7 @@
|
|||||||
android:hint="@string/message_content"
|
android:hint="@string/message_content"
|
||||||
android:imeOptions="flagNoExtractUi"
|
android:imeOptions="flagNoExtractUi"
|
||||||
android:importantForAutofill="no"
|
android:importantForAutofill="no"
|
||||||
android:inputType="textMultiLine"
|
android:inputType="textMultiLine|textCapSentences"
|
||||||
android:minHeight="58dp"
|
android:minHeight="58dp"
|
||||||
android:paddingStart="16dp"
|
android:paddingStart="16dp"
|
||||||
android:paddingLeft="16dp"
|
android:paddingLeft="16dp"
|
||||||
|
@ -153,8 +153,8 @@
|
|||||||
android:background="?selectableItemBackgroundBorderless"
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
android:fontFamily="sans-serif"
|
android:fontFamily="sans-serif"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/app_name"
|
android:textSize="16sp"
|
||||||
android:textSize="16sp" />
|
tools:text="@tools:sample/date/ddmmyy" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/attendanceNextButton"
|
android:id="@+id/attendanceNextButton"
|
||||||
|
@ -138,8 +138,8 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fontFamily="sans-serif"
|
android:fontFamily="sans-serif"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/app_name"
|
android:textSize="16sp"
|
||||||
android:textSize="16sp" />
|
tools:text="@tools:sample/date/ddmmyy" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/examNextButton"
|
android:id="@+id/examNextButton"
|
||||||
|
@ -138,8 +138,8 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fontFamily="sans-serif"
|
android:fontFamily="sans-serif"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/app_name"
|
android:textSize="16sp"
|
||||||
android:textSize="16sp" />
|
tools:text="@tools:sample/date/ddmmyy" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/homeworkNextButton"
|
android:id="@+id/homeworkNextButton"
|
||||||
|
@ -67,7 +67,6 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:layout_marginRight="8dp"
|
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="@string/login_contact_email"
|
android:text="@string/login_contact_email"
|
||||||
app:icon="@drawable/ic_more_messages" />
|
app:icon="@drawable/ic_more_messages" />
|
||||||
@ -78,7 +77,6 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginLeft="8dp"
|
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="@string/about_faq"
|
android:text="@string/about_faq"
|
||||||
app:icon="@drawable/ic_about_faq" />
|
app:icon="@drawable/ic_about_faq" />
|
||||||
@ -182,7 +180,6 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="24dp"
|
android:layout_marginEnd="24dp"
|
||||||
android:layout_marginRight="24dp"
|
|
||||||
android:text="@string/login_recover_button"
|
android:text="@string/login_recover_button"
|
||||||
android:textAppearance="?android:textAppearance"
|
android:textAppearance="?android:textAppearance"
|
||||||
app:backgroundTint="?android:windowBackground"
|
app:backgroundTint="?android:windowBackground"
|
||||||
@ -223,9 +220,9 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:layout_marginRight="16dp"
|
|
||||||
android:text="@string/login_advanced"
|
android:text="@string/login_advanced"
|
||||||
android:textAppearance="?android:textAppearance"
|
android:textAppearance="?android:textAppearance"
|
||||||
|
android:visibility="gone"
|
||||||
app:backgroundTint="?android:windowBackground"
|
app:backgroundTint="?android:windowBackground"
|
||||||
app:fontFamily="sans-serif-medium"
|
app:fontFamily="sans-serif-medium"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/loginFormSignIn"
|
app:layout_constraintBottom_toBottomOf="@id/loginFormSignIn"
|
||||||
@ -241,7 +238,6 @@
|
|||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:layout_marginTop="48dp"
|
android:layout_marginTop="48dp"
|
||||||
android:layout_marginEnd="24dp"
|
android:layout_marginEnd="24dp"
|
||||||
android:layout_marginRight="24dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
android:layout_marginBottom="16dp"
|
||||||
android:text="@string/login_sign_in"
|
android:text="@string/login_sign_in"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
@ -24,10 +24,10 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
android:visibility="gone"
|
|
||||||
tools:visibility="visible">
|
tools:visibility="visible">
|
||||||
|
|
||||||
<View
|
<View
|
||||||
@ -42,9 +42,9 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="32dp"
|
android:layout_marginStart="32dp"
|
||||||
android:layout_marginLeft="32dp"
|
android:layout_marginLeft="32dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
android:layout_marginEnd="32dp"
|
android:layout_marginEnd="32dp"
|
||||||
android:layout_marginRight="32dp"
|
android:layout_marginRight="32dp"
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
android:layout_marginBottom="16dp"
|
||||||
android:gravity="center_horizontal"
|
android:gravity="center_horizontal"
|
||||||
android:text="@string/login_contact_header"
|
android:text="@string/login_contact_header"
|
||||||
@ -55,28 +55,29 @@
|
|||||||
android:id="@+id/loginStudentSelectContactButtons"
|
android:id="@+id/loginStudentSelectContactButtons"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginLeft="16dp"
|
||||||
android:layout_marginRight="16dp">
|
android:layout_marginRight="16dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
|
||||||
android:id="@+id/loginStudentSelectContactEmail"
|
android:id="@+id/loginStudentSelectContactEmail"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_marginRight="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
|
android:layout_weight="1"
|
||||||
android:text="@string/login_contact_email"
|
android:text="@string/login_contact_email"
|
||||||
app:icon="@drawable/ic_more_messages" />
|
app:icon="@drawable/ic_more_messages" />
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
|
||||||
android:id="@+id/loginStudentSelectContactDiscord"
|
android:id="@+id/loginStudentSelectContactDiscord"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_marginLeft="8dp"
|
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_weight="1"
|
||||||
android:text="@string/login_contact_discord"
|
android:text="@string/login_contact_discord"
|
||||||
app:icon="@drawable/ic_about_discord" />
|
app:icon="@drawable/ic_about_discord" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@ -95,9 +96,9 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="32dp"
|
android:layout_marginStart="32dp"
|
||||||
android:layout_marginLeft="32dp"
|
android:layout_marginLeft="32dp"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
android:layout_marginEnd="32dp"
|
android:layout_marginEnd="32dp"
|
||||||
android:layout_marginRight="32dp"
|
android:layout_marginRight="32dp"
|
||||||
android:layout_marginTop="32dp"
|
|
||||||
android:layout_marginBottom="32dp"
|
android:layout_marginBottom="32dp"
|
||||||
android:gravity="center_horizontal"
|
android:gravity="center_horizontal"
|
||||||
android:text="@string/login_select_student"
|
android:text="@string/login_select_student"
|
||||||
@ -129,8 +130,8 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="32dp"
|
android:layout_marginTop="32dp"
|
||||||
android:layout_marginEnd="24dp"
|
android:layout_marginEnd="24dp"
|
||||||
android:layout_marginRight="24dp"
|
|
||||||
android:layout_marginBottom="32dp"
|
android:layout_marginBottom="32dp"
|
||||||
|
android:enabled="false"
|
||||||
android:text="@string/login_sign_in"
|
android:text="@string/login_sign_in"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -139,8 +139,8 @@
|
|||||||
android:background="?selectableItemBackgroundBorderless"
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
android:fontFamily="sans-serif"
|
android:fontFamily="sans-serif"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/app_name"
|
android:textSize="16sp"
|
||||||
android:textSize="16sp" />
|
tools:text="@tools:sample/date/ddmmyy" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/timetableNextButton"
|
android:id="@+id/timetableNextButton"
|
||||||
|
@ -115,8 +115,8 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
android:layout_gravity="bottom"
|
android:layout_gravity="bottom"
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal"
|
||||||
tools:ignore="UnusedAttribute">
|
tools:ignore="UnusedAttribute">
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
@ -125,24 +125,24 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:contentDescription="@string/all_prev"
|
||||||
android:paddingLeft="12dp"
|
android:paddingLeft="12dp"
|
||||||
android:paddingTop="8dp"
|
android:paddingTop="8dp"
|
||||||
android:paddingRight="12dp"
|
android:paddingRight="12dp"
|
||||||
android:paddingBottom="8dp"
|
android:paddingBottom="8dp"
|
||||||
android:scaleType="fitStart"
|
android:scaleType="fitStart"
|
||||||
android:tint="?colorPrimary"
|
android:tint="?colorPrimary"
|
||||||
app:srcCompat="@drawable/ic_chevron_left"
|
app:srcCompat="@drawable/ic_chevron_left" />
|
||||||
android:contentDescription="@string/all_prev"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/completedLessonsNavDate"
|
android:id="@+id/completedLessonsNavDate"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fontFamily="sans-serif"
|
|
||||||
android:background="?selectableItemBackgroundBorderless"
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
|
android:fontFamily="sans-serif"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/app_name"
|
android:textSize="16sp"
|
||||||
android:textSize="16sp" />
|
tools:text="@tools:sample/date/ddmmyy" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/completedLessonsNextButton"
|
android:id="@+id/completedLessonsNextButton"
|
||||||
@ -150,13 +150,13 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:contentDescription="@string/all_next"
|
||||||
android:paddingLeft="12dp"
|
android:paddingLeft="12dp"
|
||||||
android:paddingTop="8dp"
|
android:paddingTop="8dp"
|
||||||
android:paddingRight="12dp"
|
android:paddingRight="12dp"
|
||||||
android:paddingBottom="8dp"
|
android:paddingBottom="8dp"
|
||||||
android:scaleType="fitEnd"
|
android:scaleType="fitEnd"
|
||||||
android:tint="?colorPrimary"
|
android:tint="?colorPrimary"
|
||||||
app:srcCompat="@drawable/ic_chevron_right"
|
app:srcCompat="@drawable/ic_chevron_right" />
|
||||||
android:contentDescription="@string/all_next" />
|
|
||||||
</io.github.wulkanowy.ui.widgets.MaterialLinearLayout>
|
</io.github.wulkanowy.ui.widgets.MaterialLinearLayout>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Wulkanowy</string>
|
|
||||||
<!--Activity/Fragment title-->
|
<!--Activity/Fragment title-->
|
||||||
<string name="login_title">Anmelden</string>
|
<string name="login_title">Anmelden</string>
|
||||||
<string name="main_title">Wulkanowy</string>
|
<string name="main_title">Wulkanowy</string>
|
||||||
@ -270,6 +269,9 @@
|
|||||||
<!--Log viewer-->
|
<!--Log viewer-->
|
||||||
<string name="logviewer_share">Logs teilen</string>
|
<string name="logviewer_share">Logs teilen</string>
|
||||||
<string name="logviewer_refresh">Aktualisieren</string>
|
<string name="logviewer_refresh">Aktualisieren</string>
|
||||||
|
<!--Error dialog-->
|
||||||
|
<string name="dialog_error_check_update">Check for updates</string>
|
||||||
|
<string name="dialog_error_check_update_message">Before reporting a bug, check first if an update with the bug fix is available</string>
|
||||||
<!--Generic-->
|
<!--Generic-->
|
||||||
<string name="all_content">Inhalt</string>
|
<string name="all_content">Inhalt</string>
|
||||||
<string name="all_retry">Wiederhol</string>
|
<string name="all_retry">Wiederhol</string>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Wulkanowy</string>
|
|
||||||
<!--Activity/Fragment title-->
|
<!--Activity/Fragment title-->
|
||||||
<string name="login_title">Logowanie</string>
|
<string name="login_title">Logowanie</string>
|
||||||
<string name="main_title">Wulkanowy</string>
|
<string name="main_title">Wulkanowy</string>
|
||||||
@ -48,7 +47,7 @@
|
|||||||
<string name="login_incorrect_symbol">Nie znaleziono ucznia. Sprawdź symbol</string>
|
<string name="login_incorrect_symbol">Nie znaleziono ucznia. Sprawdź symbol</string>
|
||||||
<string name="login_field_required">To pole jest wymagane</string>
|
<string name="login_field_required">To pole jest wymagane</string>
|
||||||
<string name="login_duplicate_student">Wybrany uczeń jest już zalogowany</string>
|
<string name="login_duplicate_student">Wybrany uczeń jest już zalogowany</string>
|
||||||
<string name="login_symbol_helper">Symbol znajdziesz na stronie dziennika w <b>Uczeń</b> → <b>Dostęp Mobilny</b> → <b>Zarejestruj urządzenie mobilne</b></string>
|
<string name="login_symbol_helper">Symbol znajdziesz na stronie dziennika w <b>Uczeń</b> → <b>Dostęp Mobilny</b> → <b>Zarejestruj urządzenie mobilne</b>.\n\nUpewnij się, że w polu <b>Dziennik UONET+</b> na poprzednim ekranie został ustawiony odpowiedni dziennik</string>
|
||||||
<string name="login_select_student">Wybierz uczniów do zalogowania w aplikacji</string>
|
<string name="login_select_student">Wybierz uczniów do zalogowania w aplikacji</string>
|
||||||
<string name="login_advanced">Inne opcje</string>
|
<string name="login_advanced">Inne opcje</string>
|
||||||
<string name="login_advanced_warning_mobile_api">W tym trybie nie działa szczęśliwy numerek, uczeń na tle klasy, podsumowanie frekwencji, usprawiedliwianie nieobecności, lekcje zrealizowane, informacje o szkole i podgląd listy zarejestrowanych urządzeń</string>
|
<string name="login_advanced_warning_mobile_api">W tym trybie nie działa szczęśliwy numerek, uczeń na tle klasy, podsumowanie frekwencji, usprawiedliwianie nieobecności, lekcje zrealizowane, informacje o szkole i podgląd listy zarejestrowanych urządzeń</string>
|
||||||
@ -290,6 +289,9 @@
|
|||||||
<!--Log viewer-->
|
<!--Log viewer-->
|
||||||
<string name="logviewer_share">Udostępnij logi</string>
|
<string name="logviewer_share">Udostępnij logi</string>
|
||||||
<string name="logviewer_refresh">Odśwież</string>
|
<string name="logviewer_refresh">Odśwież</string>
|
||||||
|
<!--Error dialog-->
|
||||||
|
<string name="dialog_error_check_update">Sprawdź dostępność aktualizacji</string>
|
||||||
|
<string name="dialog_error_check_update_message">Przed zgłoszeniem błędu sprawdź wcześniej, czy dostępna jest już aktualizacja z poprawką błędu</string>
|
||||||
<!--Generic-->
|
<!--Generic-->
|
||||||
<string name="all_content">Treść</string>
|
<string name="all_content">Treść</string>
|
||||||
<string name="all_retry">Ponów</string>
|
<string name="all_retry">Ponów</string>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Wulkanowy</string>
|
|
||||||
<!--Activity/Fragment title-->
|
<!--Activity/Fragment title-->
|
||||||
<string name="login_title">Авторизация</string>
|
<string name="login_title">Авторизация</string>
|
||||||
<string name="main_title">Wulkanowy</string>
|
<string name="main_title">Wulkanowy</string>
|
||||||
@ -121,14 +120,14 @@
|
|||||||
<string name="timetable_time">Часы</string>
|
<string name="timetable_time">Часы</string>
|
||||||
<string name="timetable_changes">Изменения</string>
|
<string name="timetable_changes">Изменения</string>
|
||||||
<string name="timetable_no_items">Нет уроков в данный день</string>
|
<string name="timetable_no_items">Нет уроков в данный день</string>
|
||||||
<string name="timetable_minutes">%s min</string>
|
<string name="timetable_minutes">%s мин</string>
|
||||||
<string name="timetable_seconds">%s sec</string>
|
<string name="timetable_seconds">%s сек</string>
|
||||||
<string name="timetable_time_left">%1$s left</string>
|
<string name="timetable_time_left">%1$s осталось</string>
|
||||||
<string name="timetable_time_until">in %1$s</string>
|
<string name="timetable_time_until">через %1$s</string>
|
||||||
<string name="timetable_finished">Finished</string>
|
<string name="timetable_finished">Окончен</string>
|
||||||
<string name="timetable_now">Now: %s</string>
|
<string name="timetable_now">Сейчас: %s</string>
|
||||||
<string name="timetable_next">Next: %s</string>
|
<string name="timetable_next">Следующий: %s</string>
|
||||||
<string name="timetable_later">Later: %s</string>
|
<string name="timetable_later">Позже: %s</string>
|
||||||
<!--Completed lessons-->
|
<!--Completed lessons-->
|
||||||
<string name="completed_lessons_title">Проведённые уроки</string>
|
<string name="completed_lessons_title">Проведённые уроки</string>
|
||||||
<string name="completed_lessons_button">Просмотреть проведённые уроки</string>
|
<string name="completed_lessons_button">Просмотреть проведённые уроки</string>
|
||||||
@ -290,6 +289,9 @@
|
|||||||
<!--Log viewer-->
|
<!--Log viewer-->
|
||||||
<string name="logviewer_share">Поделиться логами</string>
|
<string name="logviewer_share">Поделиться логами</string>
|
||||||
<string name="logviewer_refresh">Обновить</string>
|
<string name="logviewer_refresh">Обновить</string>
|
||||||
|
<!--Error dialog-->
|
||||||
|
<string name="dialog_error_check_update">Проверить наличие обновлений</string>
|
||||||
|
<string name="dialog_error_check_update_message">Прежде чем сообщать об ошибке, проверьте наличие обновлений</string>
|
||||||
<!--Generic-->
|
<!--Generic-->
|
||||||
<string name="all_content">Содержание</string>
|
<string name="all_content">Содержание</string>
|
||||||
<string name="all_retry">Повторить</string>
|
<string name="all_retry">Повторить</string>
|
||||||
@ -306,8 +308,8 @@
|
|||||||
<string name="all_subject">Предмет</string>
|
<string name="all_subject">Предмет</string>
|
||||||
<string name="all_prev">Предыдущий</string>
|
<string name="all_prev">Предыдущий</string>
|
||||||
<string name="all_next">Следующий</string>
|
<string name="all_next">Следующий</string>
|
||||||
<string name="all_search">Search</string>
|
<string name="all_search">Поиск</string>
|
||||||
<string name="all_search_hint">Search...</string>
|
<string name="all_search_hint">Поиск...</string>
|
||||||
<!--Timetable Widget-->
|
<!--Timetable Widget-->
|
||||||
<string name="widget_timetable_no_items">Нет уроков</string>
|
<string name="widget_timetable_no_items">Нет уроков</string>
|
||||||
<string name="widget_timetable_theme_title">Выбрать тему</string>
|
<string name="widget_timetable_theme_title">Выбрать тему</string>
|
||||||
@ -322,17 +324,17 @@
|
|||||||
<string name="pref_view_present">Показывать присутствия в посещаемости</string>
|
<string name="pref_view_present">Показывать присутствия в посещаемости</string>
|
||||||
<string name="pref_view_app_theme">Тема приложения</string>
|
<string name="pref_view_app_theme">Тема приложения</string>
|
||||||
<string name="pref_view_expand_grade">Больше оценок</string>
|
<string name="pref_view_expand_grade">Больше оценок</string>
|
||||||
<string name="pref_view_timetable_show_timers">Mark current lesson in timetable</string>
|
<string name="pref_view_timetable_show_timers">Отмечать текущий урок в расписании</string>
|
||||||
<string name="pref_view_grade_statistics_list">Show chart list in class grades</string>
|
<string name="pref_view_grade_statistics_list">Показывать диаграммы в оценках класса</string>
|
||||||
<string name="pref_view_timetable_show_whole_class">Показать уроки всего класса</string>
|
<string name="pref_view_timetable_show_whole_class">Показать уроки всего класса</string>
|
||||||
<string name="pref_view_grade_color_scheme">Схема цветов оценок</string>
|
<string name="pref_view_grade_color_scheme">Схема цветов оценок</string>
|
||||||
<string name="pref_view_app_language">Язык приложения</string>
|
<string name="pref_view_app_language">Язык приложения</string>
|
||||||
<string name="pref_notify_header">Уведомления</string>
|
<string name="pref_notify_header">Уведомления</string>
|
||||||
<string name="pref_notify_switch">Показывать уведомления</string>
|
<string name="pref_notify_switch">Показывать уведомления</string>
|
||||||
<string name="pref_notify_upcoming_lessons_switch">Show upcoming lesson notifications</string>
|
<string name="pref_notify_upcoming_lessons_switch">Показывать уведомления о будущих уроках</string>
|
||||||
<string name="pref_notify_fix_sync_issues">Fix synchronization & notifications issues</string>
|
<string name="pref_notify_fix_sync_issues">Исправить проблемы с синхронизацией и уведомлениями</string>
|
||||||
<string name="pref_notify_fix_sync_issues_message">Your device may have data synchronization issues and with notifications.\n\nTo fix them, you need to add Wulkanowy to the autostart and turn off battery optimization/saving in the phone settings.</string>
|
<string name="pref_notify_fix_sync_issues_message">На вашем устройстве могут быть проблемы с синхронизацией данных и уведомлениями.\n\nЧтобы их исправить, вам необходимо добавить Wulkanowy в авто-старт и выключить оптимизацию/экономию батареи в настройках устройства.</string>
|
||||||
<string name="pref_notify_fix_sync_issues_settings_button">Go to settings</string>
|
<string name="pref_notify_fix_sync_issues_settings_button">Перейти в настройски</string>
|
||||||
<string name="pref_notify_debug_switch">Показывать дебаг-уведомления</string>
|
<string name="pref_notify_debug_switch">Показывать дебаг-уведомления</string>
|
||||||
<string name="pref_services_header">Синхронизация</string>
|
<string name="pref_services_header">Синхронизация</string>
|
||||||
<string name="pref_services_switch">Автоматическая синхронизация</string>
|
<string name="pref_services_switch">Автоматическая синхронизация</string>
|
||||||
@ -358,7 +360,7 @@
|
|||||||
<string name="channel_new_message">Новые сообщения</string>
|
<string name="channel_new_message">Новые сообщения</string>
|
||||||
<string name="channel_new_notes">Новые заметки</string>
|
<string name="channel_new_notes">Новые заметки</string>
|
||||||
<string name="channel_push">Показывать push-уведомления</string>
|
<string name="channel_push">Показывать push-уведомления</string>
|
||||||
<string name="channel_upcoming_lessons">Upcoming lessons</string>
|
<string name="channel_upcoming_lessons">Будущие уроки</string>
|
||||||
<string name="channel_debug">Дебаг</string>
|
<string name="channel_debug">Дебаг</string>
|
||||||
<!--Colors-->
|
<!--Colors-->
|
||||||
<string name="all_black">Чёрный</string>
|
<string name="all_black">Чёрный</string>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Wulkanowy</string>
|
|
||||||
<!--Activity/Fragment title-->
|
<!--Activity/Fragment title-->
|
||||||
<string name="login_title">Авторизація</string>
|
<string name="login_title">Авторизація</string>
|
||||||
<string name="main_title">Wulkanowy</string>
|
<string name="main_title">Wulkanowy</string>
|
||||||
@ -121,14 +120,14 @@
|
|||||||
<string name="timetable_time">Години</string>
|
<string name="timetable_time">Години</string>
|
||||||
<string name="timetable_changes">Зміни</string>
|
<string name="timetable_changes">Зміни</string>
|
||||||
<string name="timetable_no_items">Брак уроків у цей день</string>
|
<string name="timetable_no_items">Брак уроків у цей день</string>
|
||||||
<string name="timetable_minutes">%s min</string>
|
<string name="timetable_minutes">%s хвилин</string>
|
||||||
<string name="timetable_seconds">%s sec</string>
|
<string name="timetable_seconds">%s сек</string>
|
||||||
<string name="timetable_time_left">%1$s left</string>
|
<string name="timetable_time_left">%1$s лишилося</string>
|
||||||
<string name="timetable_time_until">in %1$s</string>
|
<string name="timetable_time_until">через %1$s</string>
|
||||||
<string name="timetable_finished">Finished</string>
|
<string name="timetable_finished">Завершено</string>
|
||||||
<string name="timetable_now">Now: %s</string>
|
<string name="timetable_now">Зараз: %s</string>
|
||||||
<string name="timetable_next">Next: %s</string>
|
<string name="timetable_next">Наступний: %s</string>
|
||||||
<string name="timetable_later">Later: %s</string>
|
<string name="timetable_later">Пізніше: %s</string>
|
||||||
<!--Completed lessons-->
|
<!--Completed lessons-->
|
||||||
<string name="completed_lessons_title">Уроки, що відбулися</string>
|
<string name="completed_lessons_title">Уроки, що відбулися</string>
|
||||||
<string name="completed_lessons_button">Показати уроки, що відбулися</string>
|
<string name="completed_lessons_button">Показати уроки, що відбулися</string>
|
||||||
@ -290,6 +289,9 @@
|
|||||||
<!--Log viewer-->
|
<!--Log viewer-->
|
||||||
<string name="logviewer_share">Поділитися логами</string>
|
<string name="logviewer_share">Поділитися логами</string>
|
||||||
<string name="logviewer_refresh">Оновити</string>
|
<string name="logviewer_refresh">Оновити</string>
|
||||||
|
<!--Error dialog-->
|
||||||
|
<string name="dialog_error_check_update">Провірити наявність оновлень</string>
|
||||||
|
<string name="dialog_error_check_update_message">Перед тим, як повідомлювати о помілці, перевірте наявність оновлень</string>
|
||||||
<!--Generic-->
|
<!--Generic-->
|
||||||
<string name="all_content">Зміст</string>
|
<string name="all_content">Зміст</string>
|
||||||
<string name="all_retry">Повторити</string>
|
<string name="all_retry">Повторити</string>
|
||||||
@ -306,8 +308,8 @@
|
|||||||
<string name="all_subject">Предмет</string>
|
<string name="all_subject">Предмет</string>
|
||||||
<string name="all_prev">Попередній</string>
|
<string name="all_prev">Попередній</string>
|
||||||
<string name="all_next">Наступний</string>
|
<string name="all_next">Наступний</string>
|
||||||
<string name="all_search">Search</string>
|
<string name="all_search">Пошук</string>
|
||||||
<string name="all_search_hint">Search...</string>
|
<string name="all_search_hint">Пошук...</string>
|
||||||
<!--Timetable Widget-->
|
<!--Timetable Widget-->
|
||||||
<string name="widget_timetable_no_items">Брак уроків</string>
|
<string name="widget_timetable_no_items">Брак уроків</string>
|
||||||
<string name="widget_timetable_theme_title">Увібрати тему</string>
|
<string name="widget_timetable_theme_title">Увібрати тему</string>
|
||||||
@ -322,17 +324,17 @@
|
|||||||
<string name="pref_view_present">Показувати присутність у відвідуваності</string>
|
<string name="pref_view_present">Показувати присутність у відвідуваності</string>
|
||||||
<string name="pref_view_app_theme">Тема додатку</string>
|
<string name="pref_view_app_theme">Тема додатку</string>
|
||||||
<string name="pref_view_expand_grade">Більше оцінок</string>
|
<string name="pref_view_expand_grade">Більше оцінок</string>
|
||||||
<string name="pref_view_timetable_show_timers">Mark current lesson in timetable</string>
|
<string name="pref_view_timetable_show_timers">Позначити поточний урок у розкладі</string>
|
||||||
<string name="pref_view_grade_statistics_list">Show chart list in class grades</string>
|
<string name="pref_view_grade_statistics_list">Показувати діаграми в оцінках класу</string>
|
||||||
<string name="pref_view_timetable_show_whole_class">Показати уроки всього класу</string>
|
<string name="pref_view_timetable_show_whole_class">Показати уроки всього класу</string>
|
||||||
<string name="pref_view_grade_color_scheme">Схема кольорів оцінок</string>
|
<string name="pref_view_grade_color_scheme">Схема кольорів оцінок</string>
|
||||||
<string name="pref_view_app_language">Мова додатку</string>
|
<string name="pref_view_app_language">Мова додатку</string>
|
||||||
<string name="pref_notify_header">Повідомлення</string>
|
<string name="pref_notify_header">Повідомлення</string>
|
||||||
<string name="pref_notify_switch">Показувати повідомлення</string>
|
<string name="pref_notify_switch">Показувати повідомлення</string>
|
||||||
<string name="pref_notify_upcoming_lessons_switch">Show upcoming lesson notifications</string>
|
<string name="pref_notify_upcoming_lessons_switch">Показувати повідомлення о наступних уроках</string>
|
||||||
<string name="pref_notify_fix_sync_issues">Fix synchronization & notifications issues</string>
|
<string name="pref_notify_fix_sync_issues">Виправити помилки з синхронізацією і повідомленнями</string>
|
||||||
<string name="pref_notify_fix_sync_issues_message">Your device may have data synchronization issues and with notifications.\n\nTo fix them, you need to add Wulkanowy to the autostart and turn off battery optimization/saving in the phone settings.</string>
|
<string name="pref_notify_fix_sync_issues_message">На вашому пристрої можуть бути помилки з синхронізацією і повідомленнями\n\nЩоб виправити іх, вам необхідно додати Wulkanowy в авто-старт и вимкнути оптимізацію/экономію батареї в налаштуваннях пристрою.</string>
|
||||||
<string name="pref_notify_fix_sync_issues_settings_button">Go to settings</string>
|
<string name="pref_notify_fix_sync_issues_settings_button">Перейти до налаштувань</string>
|
||||||
<string name="pref_notify_debug_switch">Показувати дебаг-повідомлення</string>
|
<string name="pref_notify_debug_switch">Показувати дебаг-повідомлення</string>
|
||||||
<string name="pref_services_header">Синхронізація</string>
|
<string name="pref_services_header">Синхронізація</string>
|
||||||
<string name="pref_services_switch">Автоматична синхронізація</string>
|
<string name="pref_services_switch">Автоматична синхронізація</string>
|
||||||
@ -358,7 +360,7 @@
|
|||||||
<string name="channel_new_message">Нові повідомлення</string>
|
<string name="channel_new_message">Нові повідомлення</string>
|
||||||
<string name="channel_new_notes">Нові нотатки</string>
|
<string name="channel_new_notes">Нові нотатки</string>
|
||||||
<string name="channel_push">Показувати push-повідомлення</string>
|
<string name="channel_push">Показувати push-повідомлення</string>
|
||||||
<string name="channel_upcoming_lessons">Upcoming lessons</string>
|
<string name="channel_upcoming_lessons">Наступні уроки</string>
|
||||||
<string name="channel_debug">Дебаг</string>
|
<string name="channel_debug">Дебаг</string>
|
||||||
<!--Colors-->
|
<!--Colors-->
|
||||||
<string name="all_black">Чорний</string>
|
<string name="all_black">Чорний</string>
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<string name="app_name">Wulkanowy</string>
|
|
||||||
|
|
||||||
|
|
||||||
<!--Activity/Fragment title-->
|
<!--Activity/Fragment title-->
|
||||||
<string name="login_title">Login</string>
|
<string name="login_title">Login</string>
|
||||||
<string name="main_title">Wulkanowy</string>
|
<string name="main_title">Wulkanowy</string>
|
||||||
@ -321,6 +317,11 @@
|
|||||||
<string name="logviewer_refresh">Refresh</string>
|
<string name="logviewer_refresh">Refresh</string>
|
||||||
|
|
||||||
|
|
||||||
|
<!--Error dialog-->
|
||||||
|
<string name="dialog_error_check_update">Check for updates</string>
|
||||||
|
<string name="dialog_error_check_update_message">Before reporting a bug, check first if an update with the bug fix is available</string>
|
||||||
|
|
||||||
|
|
||||||
<!--Generic-->
|
<!--Generic-->
|
||||||
<string name="all_content">Content</string>
|
<string name="all_content">Content</string>
|
||||||
<string name="all_retry">Retry</string>
|
<string name="all_retry">Retry</string>
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
app:defaultValue="@bool/pref_default_grade_statistics_list"
|
app:defaultValue="@bool/pref_default_grade_statistics_list"
|
||||||
app:iconSpaceReserved="false"
|
app:iconSpaceReserved="false"
|
||||||
app:key="@string/pref_key_grade_statistics_list"
|
app:key="@string/pref_key_grade_statistics_list"
|
||||||
|
app:singleLineTitle="false"
|
||||||
app:title="@string/pref_view_grade_statistics_list" />
|
app:title="@string/pref_view_grade_statistics_list" />
|
||||||
<ListPreference
|
<ListPreference
|
||||||
app:defaultValue="@string/pref_default_timetable_show_whole_class"
|
app:defaultValue="@string/pref_default_timetable_show_whole_class"
|
||||||
@ -109,11 +110,13 @@
|
|||||||
app:defaultValue="@bool/pref_default_notification_upcoming_lessons_enable"
|
app:defaultValue="@bool/pref_default_notification_upcoming_lessons_enable"
|
||||||
app:iconSpaceReserved="false"
|
app:iconSpaceReserved="false"
|
||||||
app:key="@string/pref_key_notifications_upcoming_lessons_enable"
|
app:key="@string/pref_key_notifications_upcoming_lessons_enable"
|
||||||
|
app:singleLineTitle="false"
|
||||||
app:title="@string/pref_notify_upcoming_lessons_switch" />
|
app:title="@string/pref_notify_upcoming_lessons_switch" />
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
app:defaultValue="@bool/pref_default_notification_debug"
|
app:defaultValue="@bool/pref_default_notification_debug"
|
||||||
app:iconSpaceReserved="false"
|
app:iconSpaceReserved="false"
|
||||||
app:key="@string/pref_key_notification_debug"
|
app:key="@string/pref_key_notification_debug"
|
||||||
|
app:singleLineTitle="false"
|
||||||
app:title="@string/pref_notify_debug_switch" />
|
app:title="@string/pref_notify_debug_switch" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
@ -147,11 +150,13 @@
|
|||||||
app:defaultValue="@bool/pref_default_grade_average_force_calc"
|
app:defaultValue="@bool/pref_default_grade_average_force_calc"
|
||||||
app:iconSpaceReserved="false"
|
app:iconSpaceReserved="false"
|
||||||
app:key="@string/pref_key_grade_average_force_calc"
|
app:key="@string/pref_key_grade_average_force_calc"
|
||||||
|
app:singleLineTitle="false"
|
||||||
app:title="@string/pref_view_grade_average_force_calc" />
|
app:title="@string/pref_view_grade_average_force_calc" />
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
app:defaultValue="@bool/pref_default_fill_message_content"
|
app:defaultValue="@bool/pref_default_fill_message_content"
|
||||||
app:iconSpaceReserved="false"
|
app:iconSpaceReserved="false"
|
||||||
app:key="@string/pref_key_fill_message_content"
|
app:key="@string/pref_key_fill_message_content"
|
||||||
|
app:singleLineTitle="false"
|
||||||
app:title="@string/pref_other_fill_message_content" />
|
app:title="@string/pref_other_fill_message_content" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
@ -6,20 +6,14 @@ import fr.bipi.tressence.base.FormatterPriorityTree
|
|||||||
import fr.bipi.tressence.common.StackTraceRecorder
|
import fr.bipi.tressence.common.StackTraceRecorder
|
||||||
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
|
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
|
||||||
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
|
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
|
||||||
|
import java.io.InterruptedIOException
|
||||||
|
import java.net.SocketTimeoutException
|
||||||
import java.net.UnknownHostException
|
import java.net.UnknownHostException
|
||||||
|
|
||||||
class CrashlyticsTree : FormatterPriorityTree(Log.VERBOSE) {
|
class CrashlyticsTree : FormatterPriorityTree(Log.VERBOSE) {
|
||||||
|
|
||||||
private val crashlytics by lazy { FirebaseCrashlytics.getInstance() }
|
private val crashlytics by lazy { FirebaseCrashlytics.getInstance() }
|
||||||
|
|
||||||
override fun skipLog(priority: Int, tag: String?, message: String, t: Throwable?): Boolean {
|
|
||||||
if (t is FeatureDisabledException || t is FeatureNotAvailableException || t is UnknownHostException) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.skipLog(priority, tag, message, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
||||||
if (skipLog(priority, tag, message, t)) return
|
if (skipLog(priority, tag, message, t)) return
|
||||||
|
|
||||||
@ -31,6 +25,14 @@ class CrashlyticsExceptionTree : FormatterPriorityTree(Log.ERROR) {
|
|||||||
|
|
||||||
private val crashlytics by lazy { FirebaseCrashlytics.getInstance() }
|
private val crashlytics by lazy { FirebaseCrashlytics.getInstance() }
|
||||||
|
|
||||||
|
override fun skipLog(priority: Int, tag: String?, message: String, t: Throwable?): Boolean {
|
||||||
|
if (t is FeatureDisabledException || t is FeatureNotAvailableException || t is UnknownHostException || t is SocketTimeoutException || t is InterruptedIOException) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.skipLog(priority, tag, message, t)
|
||||||
|
}
|
||||||
|
|
||||||
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
||||||
if (skipLog(priority, tag, message, t)) return
|
if (skipLog(priority, tag, message, t)) return
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package io.github.wulkanowy.utils
|
package io.github.wulkanowy.utils
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics
|
import com.google.firebase.analytics.FirebaseAnalytics
|
||||||
@ -24,4 +25,8 @@ class FirebaseAnalyticsHelper @Inject constructor(private val context: Context)
|
|||||||
analytics.logEvent(name, this)
|
analytics.logEvent(name, this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setCurrentScreen(activity: Activity, name: String?) {
|
||||||
|
analytics.setCurrentScreen(activity, name, null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package io.github.wulkanowy.ui.modules.grade
|
package io.github.wulkanowy.ui.modules.grade
|
||||||
|
|
||||||
|
import io.github.wulkanowy.createSemesterEntity
|
||||||
import io.github.wulkanowy.data.db.entities.Grade
|
import io.github.wulkanowy.data.db.entities.Grade
|
||||||
import io.github.wulkanowy.data.db.entities.GradeSummary
|
import io.github.wulkanowy.data.db.entities.GradeSummary
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.repositories.grade.GradeRepository
|
import io.github.wulkanowy.data.repositories.grade.GradeRepository
|
||||||
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
import io.github.wulkanowy.createSemesterEntity
|
|
||||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
@ -84,8 +84,6 @@ class GradeAverageProviderTest {
|
|||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
|
|
||||||
`when`(preferencesRepository.gradeMinusModifier).thenReturn(.33)
|
|
||||||
`when`(preferencesRepository.gradePlusModifier).thenReturn(.33)
|
|
||||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
|
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
|
||||||
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
|
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
|
||||||
|
|
||||||
@ -93,7 +91,83 @@ class GradeAverageProviderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun onlyOneSemesterTest() {
|
fun `force calc current semester average with default modifiers in scraper mode`() {
|
||||||
|
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
||||||
|
`when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
|
||||||
|
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
|
||||||
|
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
|
||||||
|
|
||||||
|
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||||
|
|
||||||
|
assertEquals(3.5, items.single { it.subject == "Język polski" }.average, .0) // from details and after set custom plus/minus
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `force calc current semester average with custom modifiers in scraper mode`() {
|
||||||
|
val student = student.copy(loginMode = Sdk.Mode.SCRAPPER.name)
|
||||||
|
|
||||||
|
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
||||||
|
`when`(preferencesRepository.gradeMinusModifier).thenReturn(.33)
|
||||||
|
`when`(preferencesRepository.gradePlusModifier).thenReturn(.33)
|
||||||
|
|
||||||
|
`when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
|
||||||
|
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
|
||||||
|
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
|
||||||
|
|
||||||
|
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||||
|
|
||||||
|
assertEquals(3.5, items.single { it.subject == "Język polski" }.average, .0) // from details and after set custom plus/minus
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `force calc current semester average with custom modifiers in api mode`() {
|
||||||
|
val student = student.copy(loginMode = Sdk.Mode.API.name)
|
||||||
|
|
||||||
|
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
||||||
|
`when`(preferencesRepository.gradeMinusModifier).thenReturn(.33) // useless in this mode
|
||||||
|
`when`(preferencesRepository.gradePlusModifier).thenReturn(.33)
|
||||||
|
|
||||||
|
`when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
|
||||||
|
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
|
||||||
|
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
|
||||||
|
|
||||||
|
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||||
|
|
||||||
|
assertEquals(3.375, items.single { it.subject == "Język polski" }.average, .0) // (from details): 3.375
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `force calc current semester average with custom modifiers in hybrid mode`() {
|
||||||
|
val student = student.copy(loginMode = Sdk.Mode.HYBRID.name)
|
||||||
|
|
||||||
|
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
||||||
|
`when`(preferencesRepository.gradeMinusModifier).thenReturn(.33) // useless in this mode
|
||||||
|
`when`(preferencesRepository.gradePlusModifier).thenReturn(.33)
|
||||||
|
|
||||||
|
`when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
|
||||||
|
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
|
||||||
|
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
|
||||||
|
|
||||||
|
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||||
|
|
||||||
|
assertEquals(3.375, items.single { it.subject == "Język polski" }.average, .0) // (from details): 3.375
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `calc current semester average`() {
|
||||||
|
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
|
||||||
|
`when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
|
||||||
|
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries))
|
||||||
|
|
||||||
|
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||||
|
|
||||||
|
assertEquals(2, items.size)
|
||||||
|
assertEquals(2.9, items.single { it.subject == "Matematyka" }.average, .0) // from summary: 2,9
|
||||||
|
assertEquals(3.4, items.single { it.subject == "Fizyka" }.average, .0) // from details: 3,4
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `force calc current semester average`() {
|
||||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
||||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
|
`when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
|
||||||
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries))
|
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries))
|
||||||
@ -101,65 +175,12 @@ class GradeAverageProviderTest {
|
|||||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||||
|
|
||||||
assertEquals(2, items.size)
|
assertEquals(2, items.size)
|
||||||
assertEquals(2.5, items.single { it.subject == "Matematyka" }.average, .0)
|
assertEquals(2.5, items.single { it.subject == "Matematyka" }.average, .0) // from details: 2,5
|
||||||
assertEquals(3.0, items.single { it.subject == "Fizyka" }.average, .0)
|
assertEquals(3.0, items.single { it.subject == "Fizyka" }.average, .0) // from details: 3,0
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun onlyOneSemester_gradesWithModifiers_default() {
|
fun `force calc full year average when current is first`() {
|
||||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
|
||||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
|
|
||||||
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
|
|
||||||
|
|
||||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
|
||||||
|
|
||||||
assertEquals(3.5, items.single { it.subject == "Język polski" }.average, .0)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun onlyOneSemester_gradesWithModifiers_api() {
|
|
||||||
val student = student.copy(loginMode = Sdk.Mode.API.name)
|
|
||||||
|
|
||||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
|
||||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
|
|
||||||
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
|
|
||||||
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
|
|
||||||
|
|
||||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
|
||||||
|
|
||||||
assertEquals(3.375, items.single { it.subject == "Język polski" }.average, .0)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun onlyOneSemester_gradesWithModifiers_scrapper() {
|
|
||||||
val student = student.copy(loginMode = Sdk.Mode.SCRAPPER.name)
|
|
||||||
|
|
||||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
|
||||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
|
|
||||||
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
|
|
||||||
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
|
|
||||||
|
|
||||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
|
||||||
|
|
||||||
assertEquals(3.5, items.single { it.subject == "Język polski" }.average, .0)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun onlyOneSemester_gradesWithModifiers_hybrid() {
|
|
||||||
val student = student.copy(loginMode = Sdk.Mode.HYBRID.name)
|
|
||||||
|
|
||||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
|
||||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
|
|
||||||
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
|
|
||||||
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
|
|
||||||
|
|
||||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
|
||||||
|
|
||||||
assertEquals(3.375, items.single { it.subject == "Język polski" }.average, .0)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun allYearFirstSemesterTest() {
|
|
||||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
||||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
|
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
|
||||||
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries))
|
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries))
|
||||||
@ -167,33 +188,19 @@ class GradeAverageProviderTest {
|
|||||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[1].semesterId).blockingGet()
|
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[1].semesterId).blockingGet()
|
||||||
|
|
||||||
assertEquals(2, items.size)
|
assertEquals(2, items.size)
|
||||||
assertEquals(3.5, items.single { it.subject == "Matematyka" }.average, .0)
|
assertEquals(3.5, items.single { it.subject == "Matematyka" }.average, .0) // (from summary): 3,5
|
||||||
assertEquals(3.5, items.single { it.subject == "Fizyka" }.average, .0)
|
assertEquals(3.5, items.single { it.subject == "Fizyka" }.average, .0) // (from summary): 3,5
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun allYearSecondSemesterTest() {
|
|
||||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
|
||||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
|
|
||||||
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries))
|
|
||||||
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries))
|
|
||||||
|
|
||||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
|
||||||
|
|
||||||
assertEquals(2, items.size)
|
|
||||||
assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0)
|
|
||||||
assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException::class)
|
@Test(expected = IllegalArgumentException::class)
|
||||||
fun incorrectAverageModeTest() {
|
fun `calc average on invalid mode`() {
|
||||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("test_mode")
|
`when`(preferencesRepository.gradeAverageMode).thenReturn("test_mode")
|
||||||
|
|
||||||
gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).blockingGet()
|
gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).blockingGet()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun allYearSemester_averageFromSummary() {
|
fun `calc full year average`() {
|
||||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
|
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
|
||||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
|
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
|
||||||
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to listOf(
|
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to listOf(
|
||||||
@ -208,14 +215,14 @@ class GradeAverageProviderTest {
|
|||||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||||
|
|
||||||
assertEquals(2, items.size)
|
assertEquals(2, items.size)
|
||||||
assertEquals(3.25, items.single { it.subject == "Matematyka" }.average, .0)
|
assertEquals(3.25, items.single { it.subject == "Matematyka" }.average, .0) // (from summaries ↑): 3,0 + 3,5 → 3,25
|
||||||
assertEquals(3.75, items.single { it.subject == "Fizyka" }.average, .0)
|
assertEquals(3.75, items.single { it.subject == "Fizyka" }.average, .0) // (from summaries ↑): 3,5 + 4,0 → 3,75
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun onlyOneSemester_averageFromSummary_forceCalc() {
|
fun `force calc full year average`() {
|
||||||
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
|
|
||||||
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
||||||
|
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
|
||||||
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries))
|
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries))
|
||||||
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to listOf(
|
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to listOf(
|
||||||
getSummary(22, "Matematyka", 1.1),
|
getSummary(22, "Matematyka", 1.1),
|
||||||
@ -225,8 +232,102 @@ class GradeAverageProviderTest {
|
|||||||
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||||
|
|
||||||
assertEquals(2, items.size)
|
assertEquals(2, items.size)
|
||||||
assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0)
|
assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0) // (from details): 3,5 + 2,5 → 3,0
|
||||||
assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0)
|
assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `calc full year average when no summaries`() {
|
||||||
|
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
|
||||||
|
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
|
||||||
|
|
||||||
|
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to emptyList()))
|
||||||
|
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to emptyList()))
|
||||||
|
|
||||||
|
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||||
|
|
||||||
|
assertEquals(2, items.size)
|
||||||
|
assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0) // (from details): 2,5 + 3,5 → 3,0
|
||||||
|
assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `force calc full year average when no summaries`() {
|
||||||
|
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
||||||
|
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
|
||||||
|
|
||||||
|
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to emptyList()))
|
||||||
|
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to emptyList()))
|
||||||
|
|
||||||
|
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||||
|
|
||||||
|
assertEquals(2, items.size)
|
||||||
|
assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0) // (from details): 3,5 + 2,5 → 3,0
|
||||||
|
assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `calc full year average when missing summaries in both semesters`() {
|
||||||
|
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
|
||||||
|
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
|
||||||
|
|
||||||
|
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to listOf(
|
||||||
|
getSummary(22, "Matematyka", 4.0)
|
||||||
|
)))
|
||||||
|
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to listOf(
|
||||||
|
getSummary(23, "Matematyka", 3.0)
|
||||||
|
)))
|
||||||
|
|
||||||
|
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||||
|
|
||||||
|
assertEquals(2, items.size)
|
||||||
|
assertEquals(3.5, items.single { it.subject == "Matematyka" }.average, .0) // (from summaries ↑): 4,0 + 3,0 → 3,5
|
||||||
|
assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `calc full year average when missing summary in second semester`() {
|
||||||
|
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
|
||||||
|
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
|
||||||
|
|
||||||
|
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries))
|
||||||
|
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries.dropLast(1)))
|
||||||
|
|
||||||
|
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||||
|
|
||||||
|
assertEquals(2, items.size)
|
||||||
|
assertEquals(3.4, items.single { it.subject == "Matematyka" }.average, .0) // (from summaries): 3,9 + 2,9 → 3,4
|
||||||
|
assertEquals(3.05, items.single { it.subject == "Fizyka" }.average, .0) // 3,1 (from summary) + 3,0 (from details) → 3,05
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `calc full year average when missing summary in first semester`() {
|
||||||
|
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
|
||||||
|
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
|
||||||
|
|
||||||
|
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries.dropLast(1)))
|
||||||
|
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries))
|
||||||
|
|
||||||
|
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||||
|
|
||||||
|
assertEquals(2, items.size)
|
||||||
|
assertEquals(3.4, items.single { it.subject == "Matematyka" }.average, .0) // (from summaries): 3,9 + 2,9 → 3,4
|
||||||
|
assertEquals(3.45, items.single { it.subject == "Fizyka" }.average, .0) // 3,5 (from details) + 3,4 (from summary) → 3,45
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `force calc full year average when missing summary in first semester`() {
|
||||||
|
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
|
||||||
|
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
|
||||||
|
|
||||||
|
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries.dropLast(1)))
|
||||||
|
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries))
|
||||||
|
|
||||||
|
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
|
||||||
|
|
||||||
|
assertEquals(2, items.size)
|
||||||
|
assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0) // (from details): 3,5 + 2,5 → 3,0
|
||||||
|
assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getGrade(semesterId: Int, subject: String, value: Double, modifier: Double = 0.0): Grade {
|
private fun getGrade(semesterId: Int, subject: String, value: Double, modifier: Double = 0.0): Grade {
|
||||||
|
@ -38,12 +38,12 @@ class TimeExtensionTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun fridayTest() {
|
fun sundayTestTest() {
|
||||||
assertEquals(of(2018, 10, 5), of(2018, 10, 2).friday)
|
assertEquals(of(2018, 10, 7), of(2018, 10, 2).sunday)
|
||||||
assertEquals(of(2018, 10, 5), of(2018, 10, 5).friday)
|
assertEquals(of(2018, 10, 7), of(2018, 10, 5).sunday)
|
||||||
assertEquals(of(2018, 10, 5), of(2018, 10, 6).friday)
|
assertEquals(of(2018, 10, 7), of(2018, 10, 6).sunday)
|
||||||
assertEquals(of(2018, 10, 5), of(2018, 10, 7).friday)
|
assertEquals(of(2018, 10, 7), of(2018, 10, 7).sunday)
|
||||||
assertEquals(of(2018, 10, 12), of(2018, 10, 8).friday)
|
assertEquals(of(2018, 10, 14), of(2018, 10, 8).sunday)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.3.72'
|
ext.kotlin_version = '1.3.72'
|
||||||
ext.about_libraries = '8.1.2'
|
ext.about_libraries = '8.1.6'
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
google()
|
google()
|
||||||
@ -9,9 +9,9 @@ buildscript {
|
|||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
classpath 'com.android.tools.build:gradle:3.6.3'
|
classpath 'com.android.tools.build:gradle:4.0.0'
|
||||||
classpath 'com.google.gms:google-services:4.3.3'
|
classpath 'com.google.gms:google-services:4.3.3'
|
||||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.1.0'
|
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.1.1'
|
||||||
classpath "com.github.triplet.gradle:play-publisher:2.7.5"
|
classpath "com.github.triplet.gradle:play-publisher:2.7.5"
|
||||||
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.8"
|
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.8"
|
||||||
classpath "gradle.plugin.com.star-zero.gradle:githook:1.2.0"
|
classpath "gradle.plugin.com.star-zero.gradle:githook:1.2.0"
|
||||||
|
Reference in New Issue
Block a user