1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2025-02-07 20:14:36 +01:00

Merge branch 'release/0.18.1'

This commit is contained in:
Mikołaj Pich 2020-05-24 21:20:23 +02:00
commit 064998129e
67 changed files with 383 additions and 213 deletions

View File

@ -14,7 +14,7 @@ cache:
branches: branches:
only: only:
- develop - develop
- 0.18.0 - 0.18.1
android: android:
licenses: licenses:

View File

@ -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 60
versionName "0.18.0" versionName "0.18.1"
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')
@ -122,7 +124,7 @@ configurations.all {
} }
dependencies { dependencies {
implementation "io.github.wulkanowy:sdk:0.18.0" implementation "io.github.wulkanowy:sdk:0.18.1"
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'

View File

@ -1,3 +0,0 @@
<resources>
<string name="app_name">Wulkanowy DEV</string>
</resources>

View File

@ -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?) {}
} }

View File

@ -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
}
} }

View File

@ -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 } }
} }

View File

@ -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 } }
} }

View File

@ -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 } }
} }

View File

@ -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 {

View File

@ -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) }
} }
} }

View File

@ -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) } }
} }
} }

View File

@ -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 {

View File

@ -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()
} }
} }

View File

@ -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()
} }
} }

View File

@ -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()
} }
} }

View File

@ -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()
} }
} }

View File

@ -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()
} }
} }

View File

@ -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),

View File

@ -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 = {

View File

@ -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 -> {

View File

@ -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()

View File

@ -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)

View File

@ -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)

View File

@ -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"))
} }
} }
} }

View File

@ -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")

View File

@ -14,6 +14,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>() {
@ -38,12 +39,26 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
} }
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 } if (headers.any { it.value !is GradeDetailsHeader }) {
Timber.e("Headers contains no-header items! $headers")
}
val candidates = headers.filter { (it.value as GradeDetailsHeader).subject == subject }
if (candidates.size > 1) {
Timber.e("Header with subject $subject found ${candidates.size} times! Items: $candidates, expanded: $expandedPosition")
}
return candidates.first()
} }
fun updateHeaderItem(item: GradeDetailsItem) { fun updateHeaderItem(item: GradeDetailsItem) {
@ -92,7 +107,7 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
is ItemViewHolder -> bindItemViewHolder( is ItemViewHolder -> bindItemViewHolder(
binding = holder.binding, binding = holder.binding,
grade = items[position].value as Grade, grade = items[position].value as Grade,
position = position position = holder.adapterPosition
) )
} }
} }

View File

@ -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,10 +176,13 @@ 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,

View File

@ -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)

View File

@ -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,8 @@ 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) .sortedBy { it.subject }
} .map { it.summary.copy(average = it.average) }
}
private fun checkEmpty(gradeSummary: GradeSummary, averages: List<Triple<String, Double, String>>): Boolean {
return gradeSummary.run {
finalGrade.isBlank() && predictedGrade.isBlank() && averages.singleOrNull { it.first == subject } == null
}
} }
} }

View File

@ -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"))
} }
} }
} }

View File

@ -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()

View File

@ -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)

View File

@ -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

View File

@ -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 }) }

View File

@ -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()

View File

@ -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) }

View File

@ -77,7 +77,7 @@ 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 { onClickListener(item, holder.adapterPosition) }
} }
} }

View File

@ -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)
} }

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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) { _, _ ->
try {
AppKillerManager.doActionPowerSaving(requireContext()) AppKillerManager.doActionPowerSaving(requireContext())
AppKillerManager.doActionAutoStart(requireContext()) AppKillerManager.doActionAutoStart(requireContext())
AppKillerManager.doActionNotification(requireContext()) AppKillerManager.doActionNotification(requireContext())
} catch (e: NoActionFoundException) {
requireContext().openInternetBrowser("https://dontkillmyapp.com/${AppKillerManager.getDevice()?.manufacturer}", ::showMessage)
}
} }
.show() .show()
} }

View File

@ -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

View File

@ -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)

View File

@ -134,7 +134,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)

View File

@ -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))

View File

@ -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 })
} }
} }
} }

View File

@ -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 {

View File

@ -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)

View File

@ -1,10 +1,8 @@
Wersja 0.18.0 Wersja 0.18.1
- naprawiliśmy odświeżanie zadań domowych - naprawiliśmy sortowanie w ocenach
- naprawiliśmy powiadomienia na androidzie 8.0 - naprawilismy wiele problemów ze stabilnością
- oceny powinny się teraz odświeżać trochę szybciej - nazwy opcji w ustawieniach nie są już ucięte
- dodaliśmy tryb pełnoekranowy w zadaniach - w zadaniach domowych wyświetlają się teraz pozycje na weekend
- dodaliśmy wyszukiwanie w wiadomościach - wyłączyliśmy logowanie przez token (bo nie działa i nie wiadomo kiedy będzie działać)
- dodaliśmy opcje oznaczania bieżącej lekcji na planie/w powiadomieniu (domyślnie wyłączone)
- 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

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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>

View File

@ -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>

View File

@ -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&#160;<b>Uczeń</b> &#160;<b>Dostęp Mobilny</b>&#160;<b>Zarejestruj urządzenie mobilne</b></string> <string name="login_symbol_helper">Symbol znajdziesz na stronie dziennika w&#160;<b>Uczeń</b> &#160;<b>Dostęp Mobilny</b>&#160;<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>

View File

@ -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">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">Содержание</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 &amp; 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>

View File

@ -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>
@ -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">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">Зміст</string> <string name="all_content">Зміст</string>
<string name="all_retry">Повторити</string> <string name="all_retry">Повторити</string>

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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)
}
} }

View File

@ -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

View File

@ -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.3'
repositories { repositories {
mavenCentral() mavenCentral()
google() google()
@ -11,7 +11,7 @@ buildscript {
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:3.6.3'
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"