forked from github/wulkanowy-mirror
Merge branch 'release/0.17.2'
This commit is contained in:
commit
7fa333cff2
@ -14,7 +14,7 @@ cache:
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
- 0.17.1
|
||||
- 0.17.2
|
||||
|
||||
android:
|
||||
licenses:
|
||||
|
@ -18,8 +18,8 @@ android {
|
||||
testApplicationId "io.github.tests.wulkanowy"
|
||||
minSdkVersion 17
|
||||
targetSdkVersion 29
|
||||
versionCode 55
|
||||
versionName "0.17.1"
|
||||
versionCode 56
|
||||
versionName "0.17.2"
|
||||
multiDexEnabled true
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
@ -128,7 +128,7 @@ configurations.all {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "io.github.wulkanowy:sdk:0.17.1"
|
||||
implementation "io.github.wulkanowy:sdk:0.17.2"
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
implementation "androidx.core:core-ktx:1.2.0"
|
||||
@ -139,10 +139,10 @@ dependencies {
|
||||
implementation "androidx.annotation:annotation:1.1.0"
|
||||
implementation "androidx.multidex:multidex:2.0.1"
|
||||
|
||||
implementation "androidx.preference:preference-ktx:1.1.0"
|
||||
implementation "androidx.preference:preference-ktx:1.1.1"
|
||||
implementation "androidx.recyclerview:recyclerview:1.1.0"
|
||||
implementation "androidx.viewpager:viewpager:1.0.0"
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-beta01"
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-rc01"
|
||||
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
|
||||
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
|
||||
implementation "com.google.android.material:material:1.1.0"
|
||||
|
@ -4,6 +4,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.getCurrentOrLast
|
||||
import io.github.wulkanowy.utils.isCurrent
|
||||
import io.github.wulkanowy.utils.uniqueSubtract
|
||||
@ -20,10 +21,12 @@ class SemesterRepository @Inject constructor(
|
||||
) {
|
||||
|
||||
fun getSemesters(student: Student, forceRefresh: Boolean = false, refreshOnNoCurrent: Boolean = false): Single<List<Semester>> {
|
||||
return local.getSemesters(student).filter { !forceRefresh }.filter {
|
||||
if (refreshOnNoCurrent) {
|
||||
it.any { semester -> semester.isCurrent }
|
||||
} else true
|
||||
return local.getSemesters(student).filter { !forceRefresh }.filter { semesters ->
|
||||
when {
|
||||
Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API -> semesters.firstOrNull { it.isCurrent }?.diaryId != 0
|
||||
refreshOnNoCurrent -> semesters.any { semester -> semester.isCurrent }
|
||||
else -> true
|
||||
}
|
||||
}.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||
.flatMap {
|
||||
if (it) remote.getSemesters(student)
|
||||
|
@ -29,7 +29,7 @@ class StudentLocal @Inject constructor(
|
||||
|
||||
fun getStudents(decryptPass: Boolean): Maybe<List<Student>> {
|
||||
return studentDb.loadAll()
|
||||
.map { list -> list.map { it.apply { if (decryptPass) password = decrypt(password) } } }
|
||||
.map { list -> list.map { it.apply { if (decryptPass && Sdk.Mode.valueOf(loginMode) != Sdk.Mode.API) password = decrypt(password) } } }
|
||||
.filter { it.isNotEmpty() }
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package io.github.wulkanowy.services.sync
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build.VERSION_CODES.LOLLIPOP
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationCompat.BigTextStyle
|
||||
import androidx.core.app.NotificationCompat.PRIORITY_DEFAULT
|
||||
@ -17,9 +16,9 @@ import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
|
||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
|
||||
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
|
||||
import io.github.wulkanowy.services.sync.channels.DebugChannel
|
||||
import io.github.wulkanowy.services.sync.works.Work
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
import io.github.wulkanowy.utils.getCompatColor
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Single
|
||||
@ -33,8 +32,7 @@ class SyncWorker @AssistedInject constructor(
|
||||
private val semesterRepository: SemesterRepository,
|
||||
private val works: Set<@JvmSuppressWildcards Work>,
|
||||
private val preferencesRepository: PreferencesRepository,
|
||||
private val notificationManager: NotificationManagerCompat,
|
||||
private val appInfo: AppInfo
|
||||
private val notificationManager: NotificationManagerCompat
|
||||
) : RxWorker(appContext, workerParameters) {
|
||||
|
||||
override fun createWork(): Single<Result> {
|
||||
@ -47,6 +45,10 @@ class SyncWorker @AssistedInject constructor(
|
||||
.flatMapCompletable { semester ->
|
||||
Completable.mergeDelayError(works.map { work ->
|
||||
work.create(student, semester)
|
||||
.onErrorResumeNext {
|
||||
if (it is FeatureDisabledException || it is FeatureNotAvailableException) Completable.complete()
|
||||
else Completable.error(it)
|
||||
}
|
||||
.doOnSubscribe { Timber.i("${work::class.java.simpleName} is starting") }
|
||||
.doOnError { Timber.i("${work::class.java.simpleName} result: An exception occurred") }
|
||||
.doOnComplete { Timber.i("${work::class.java.simpleName} result: Success") }
|
||||
@ -57,11 +59,11 @@ class SyncWorker @AssistedInject constructor(
|
||||
.onErrorReturn {
|
||||
Timber.e(it, "There was an error during synchronization")
|
||||
when {
|
||||
it is FeatureDisabledException -> Result.success()
|
||||
inputData.getBoolean("one_time", false) -> {
|
||||
Result.failure(Data.Builder()
|
||||
.putString("error", it.toString())
|
||||
.build())
|
||||
.build()
|
||||
)
|
||||
}
|
||||
else -> Result.retry()
|
||||
}
|
||||
|
@ -6,19 +6,32 @@ import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.HorizontalScrollView
|
||||
import android.widget.Toast
|
||||
import android.widget.Toast.LENGTH_LONG
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
|
||||
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
|
||||
import io.github.wulkanowy.sdk.exception.ServiceUnavailableException
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
import io.github.wulkanowy.utils.getString
|
||||
import io.github.wulkanowy.utils.openEmailClient
|
||||
import io.github.wulkanowy.utils.openInternetBrowser
|
||||
import kotlinx.android.synthetic.main.dialog_error.*
|
||||
import java.io.PrintWriter
|
||||
import java.io.StringWriter
|
||||
import java.net.SocketTimeoutException
|
||||
import java.net.UnknownHostException
|
||||
import javax.inject.Inject
|
||||
|
||||
class ErrorDialog : DialogFragment() {
|
||||
class ErrorDialog : BaseDialogFragment() {
|
||||
|
||||
private lateinit var error: Throwable
|
||||
|
||||
@Inject
|
||||
lateinit var appInfo: AppInfo
|
||||
|
||||
companion object {
|
||||
private const val ARGUMENT_KEY = "Data"
|
||||
|
||||
@ -49,6 +62,9 @@ class ErrorDialog : DialogFragment() {
|
||||
}
|
||||
|
||||
errorDialogContent.text = stringWriter.toString()
|
||||
with(errorDialogHorizontalScroll) {
|
||||
post { fullScroll(HorizontalScrollView.FOCUS_LEFT) }
|
||||
}
|
||||
errorDialogCopy.setOnClickListener {
|
||||
val clip = ClipData.newPlainText("wulkanowy", stringWriter.toString())
|
||||
activity?.getSystemService<ClipboardManager>()?.setPrimaryClip(clip)
|
||||
@ -56,6 +72,29 @@ class ErrorDialog : DialogFragment() {
|
||||
Toast.makeText(context, R.string.all_copied, LENGTH_LONG).show()
|
||||
}
|
||||
errorDialogCancel.setOnClickListener { dismiss() }
|
||||
errorDialogReport.setOnClickListener { openEmailClient(stringWriter.toString()) }
|
||||
errorDialogMessage.text = resources.getString(error)
|
||||
errorDialogReport.isEnabled = when (error) {
|
||||
is UnknownHostException,
|
||||
is SocketTimeoutException,
|
||||
is ServiceUnavailableException,
|
||||
is FeatureDisabledException,
|
||||
is FeatureNotAvailableException -> false
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
private fun openEmailClient(content: String) {
|
||||
requireContext().openEmailClient(
|
||||
chooserTitle = getString(R.string.about_feedback),
|
||||
email = "wulkanowyinc@gmail.com",
|
||||
subject = "Zgłoszenie błędu",
|
||||
body = requireContext().getString(R.string.about_feedback_template,
|
||||
"${appInfo.systemManufacturer} ${appInfo.systemModel}", appInfo.systemVersion.toString(), appInfo.versionName
|
||||
) + "\n" + content,
|
||||
onActivityNotFound = {
|
||||
requireContext().openInternetBrowser("https://github.com/wulkanowy/wulkanowy/issues", ::showMessage)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,17 +2,11 @@ package io.github.wulkanowy.ui.base
|
||||
|
||||
import android.content.res.Resources
|
||||
import com.chuckerteam.chucker.api.ChuckerCollector
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
|
||||
import io.github.wulkanowy.sdk.exception.BadCredentialsException
|
||||
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
|
||||
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
|
||||
import io.github.wulkanowy.sdk.exception.NotLoggedInException
|
||||
import io.github.wulkanowy.sdk.exception.ServiceUnavailableException
|
||||
import io.github.wulkanowy.utils.getString
|
||||
import io.github.wulkanowy.utils.security.ScramblerException
|
||||
import timber.log.Timber
|
||||
import java.net.SocketTimeoutException
|
||||
import java.net.UnknownHostException
|
||||
import javax.inject.Inject
|
||||
|
||||
open class ErrorHandler @Inject constructor(protected val resources: Resources, private val chuckerCollector: ChuckerCollector) {
|
||||
@ -30,18 +24,10 @@ open class ErrorHandler @Inject constructor(protected val resources: Resources,
|
||||
}
|
||||
|
||||
protected open fun proceed(error: Throwable) {
|
||||
resources.run {
|
||||
when (error) {
|
||||
is UnknownHostException -> showErrorMessage(getString(R.string.error_no_internet), error)
|
||||
is SocketTimeoutException -> showErrorMessage(getString(R.string.error_timeout), error)
|
||||
is NotLoggedInException -> showErrorMessage(getString(R.string.error_login_failed), error)
|
||||
is ServiceUnavailableException -> showErrorMessage(getString(R.string.error_service_unavailable), error)
|
||||
is FeatureDisabledException -> showErrorMessage(getString(R.string.error_feature_disabled), error)
|
||||
is ScramblerException, is BadCredentialsException -> onSessionExpired()
|
||||
is NoCurrentStudentException -> onNoCurrentStudent()
|
||||
is FeatureNotAvailableException -> showErrorMessage(getString(R.string.error_feature_not_available), error)
|
||||
else -> showErrorMessage(getString(R.string.error_unknown), error)
|
||||
}
|
||||
else -> showErrorMessage(resources.getString(error), error)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ class GradeStatisticsPresenter @Inject constructor(
|
||||
showSubjects(true)
|
||||
}
|
||||
}, {
|
||||
Timber.e("Loading grade stats subjects result: An exception occurred")
|
||||
Timber.i("Loading grade stats subjects result: An exception occurred")
|
||||
errorHandler.dispatch(it)
|
||||
})
|
||||
)
|
||||
@ -179,7 +179,7 @@ class GradeStatisticsPresenter @Inject constructor(
|
||||
}
|
||||
analytics.logEvent("load_grade_statistics", "items" to it.size, "force_refresh" to forceRefresh)
|
||||
}) {
|
||||
Timber.e("Loading grade stats result: An exception occurred")
|
||||
Timber.i("Loading grade stats result: An exception occurred")
|
||||
errorHandler.dispatch(it)
|
||||
})
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ class LoginRecoverPresenter @Inject constructor(
|
||||
.subscribe({ (resetUrl, siteKey) ->
|
||||
view?.loadReCaptcha(siteKey, resetUrl)
|
||||
}) {
|
||||
Timber.e("Obtain captcha site key result: An exception occurred")
|
||||
Timber.i("Obtain captcha site key result: An exception occurred")
|
||||
errorHandler.dispatch(it)
|
||||
})
|
||||
}
|
||||
@ -120,7 +120,7 @@ class LoginRecoverPresenter @Inject constructor(
|
||||
|
||||
analytics.logEvent("account_recover", "register" to host, "symbol" to symbol, "success" to true)
|
||||
}) {
|
||||
Timber.e("Send recover request result: An exception occurred")
|
||||
Timber.i("Send recover request result: An exception occurred")
|
||||
errorHandler.dispatch(it)
|
||||
analytics.logEvent("account_recover", "register" to host, "symbol" to symbol, "success" to false)
|
||||
})
|
||||
|
@ -7,6 +7,7 @@ import dagger.Provides
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.di.scopes.PerFragment
|
||||
import io.github.wulkanowy.ui.base.ErrorDialog
|
||||
import io.github.wulkanowy.ui.modules.about.AboutFragment
|
||||
import io.github.wulkanowy.ui.modules.about.contributor.ContributorFragment
|
||||
import io.github.wulkanowy.ui.modules.about.license.LicenseFragment
|
||||
@ -115,6 +116,10 @@ abstract class MainModule {
|
||||
@ContributesAndroidInjector
|
||||
abstract fun bindAccountDialog(): AccountDialog
|
||||
|
||||
@PerFragment
|
||||
@ContributesAndroidInjector
|
||||
abstract fun bindErrorDialog(): ErrorDialog
|
||||
|
||||
@PerFragment
|
||||
@ContributesAndroidInjector(modules = [MobileDeviceModule::class])
|
||||
abstract fun bindMobileDevices(): MobileDeviceFragment
|
||||
@ -132,7 +137,7 @@ abstract class MainModule {
|
||||
abstract fun bindLogViewerFragment(): LogViewerFragment
|
||||
|
||||
@PerFragment
|
||||
@ContributesAndroidInjector()
|
||||
@ContributesAndroidInjector
|
||||
abstract fun bindContributorFragment(): ContributorFragment
|
||||
|
||||
@PerFragment
|
||||
|
@ -147,7 +147,7 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter>(), SendMessageVie
|
||||
}
|
||||
|
||||
override fun popView() {
|
||||
onBackPressed()
|
||||
finish()
|
||||
}
|
||||
|
||||
private fun setUpExtendedHitArea() {
|
||||
|
@ -135,12 +135,12 @@ class SendMessagePresenter @Inject constructor(
|
||||
if (selectedRecipientChips.isNotEmpty()) setSelectedRecipients(selectedRecipientChips)
|
||||
showContent(true)
|
||||
} else {
|
||||
Timber.e("Loading recipients result: Can't find the reporting unit")
|
||||
Timber.i("Loading recipients result: Can't find the reporting unit")
|
||||
view?.showEmpty(true)
|
||||
}
|
||||
}
|
||||
}, {
|
||||
Timber.e("Loading recipients result: An exception occurred")
|
||||
Timber.i("Loading recipients result: An exception occurred")
|
||||
view?.showContent(true)
|
||||
errorHandler.dispatch(it)
|
||||
}))
|
||||
|
@ -0,0 +1,20 @@
|
||||
package io.github.wulkanowy.utils
|
||||
|
||||
import android.content.res.Resources
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
|
||||
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
|
||||
import io.github.wulkanowy.sdk.exception.NotLoggedInException
|
||||
import io.github.wulkanowy.sdk.exception.ServiceUnavailableException
|
||||
import java.net.SocketTimeoutException
|
||||
import java.net.UnknownHostException
|
||||
|
||||
fun Resources.getString(error: Throwable) = when (error) {
|
||||
is UnknownHostException -> getString(R.string.error_no_internet)
|
||||
is SocketTimeoutException -> getString(R.string.error_timeout)
|
||||
is NotLoggedInException -> getString(R.string.error_login_failed)
|
||||
is ServiceUnavailableException -> getString(R.string.error_service_unavailable)
|
||||
is FeatureDisabledException -> getString(R.string.error_feature_disabled)
|
||||
is FeatureNotAvailableException -> getString(R.string.error_feature_not_available)
|
||||
else -> getString(R.string.error_unknown)
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
Wersja 0.17.1
|
||||
Wersja 0.17.2
|
||||
|
||||
- naprawiliśmy problemy ze stabilnością w szczegółach zadania domowego i podglądzie wiadomości
|
||||
- naprawiliśmy odświeżanie danych w określonych przypadkach
|
||||
- naprawiliśmy odświeżanie listy urządzeń
|
||||
- w trybie hybrydowym lista przedmiotów w zakładckach Klasa i Podsumowanie frekwencji powinna teraz zawierać tylko przedmioty ucznia
|
||||
- na liście dzienników pokazują się teraz również te niestandardowe
|
||||
- naprawiliśmy wyświetlanie przycisku oznaczania zadania domowego jako wykonanego
|
||||
- naprawiliśmy rzadki błąd ze stabilnością przy wysyłaniu wiadomości
|
||||
- naprawiliśmy błąd po logowaniu w domyślnym trybie, jeśli wcześniej użytkownik zalogowany był w trybie Mobilnego API
|
||||
- ulepszyliśmy wygląd okienka ze szczegółami błędu
|
||||
|
||||
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
||||
|
@ -1,26 +1,49 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="300dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:paddingTop="20dp"
|
||||
android:text="@string/all_details"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/errorDialogMessage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:paddingVertical="10dp"
|
||||
android:textSize="21sp"
|
||||
tools:text="@tools:sample/lorem" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/errorDialogNestedScroll"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:overScrollMode="ifContentScrolls">
|
||||
android:overScrollMode="ifContentScrolls"
|
||||
app:layout_constrainedHeight="true"
|
||||
app:layout_constraintHeight_max="300dp"
|
||||
app:layout_constraintHeight_min="200dp"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/errorDialogHorizontalScroll"
|
||||
android:layout_width="350dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingTop="24dp"
|
||||
android:paddingRight="24dp">
|
||||
|
||||
<TextView
|
||||
@ -33,16 +56,31 @@
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
</HorizontalScrollView>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:background="@drawable/ic_all_divider"
|
||||
android:gravity="end"
|
||||
android:minHeight="52dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/errorDialogReport"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:text="@string/about_feedback" />
|
||||
|
||||
<Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/errorDialogCancel"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
@ -50,7 +88,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:text="@android:string/cancel" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
@ -60,7 +97,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:text="@android:string/copy" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
@ -9,14 +9,18 @@
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/homeworkDialogRecycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:minWidth="300dp"
|
||||
tools:itemCount="1"
|
||||
tools:listitem="@layout/item_homework_dialog_details" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ic_all_divider"
|
||||
android:paddingHorizontal="10dp"
|
||||
android:paddingVertical="5dp">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/homeworkDialogRead"
|
||||
@ -25,8 +29,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="@string/homework_mark_as_done"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
@ -38,8 +40,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="@string/all_close"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
@ -1,4 +1,5 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
@ -93,6 +94,7 @@
|
||||
android:lineSpacingMultiplier="1.2"
|
||||
android:text="@string/all_no_data"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="12sp" />
|
||||
android:textSize="12sp"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -421,5 +421,5 @@
|
||||
<string name="error_service_unavailable">Trwa przerwa techniczna dziennika UONET+. Spróbuj ponownie później</string>
|
||||
<string name="error_unknown">Wystąpił nieoczekiwany błąd</string>
|
||||
<string name="error_feature_disabled">Funkcja wyłączona przez szkołę</string>
|
||||
<string name="error_feature_not_available">Funkcja niedostępna. Zaloguj się w innym trybie niż Mobilne API</string>
|
||||
<string name="error_feature_not_available">Funkcja niedostępna. Zaloguj się w trybie innym niż Mobilne API</string>
|
||||
</resources>
|
||||
|
@ -7,6 +7,9 @@ import com.crashlytics.android.core.CrashlyticsCore
|
||||
import fr.bipi.tressence.crash.CrashlyticsLogExceptionTree
|
||||
import fr.bipi.tressence.crash.CrashlyticsLogTree
|
||||
import io.fabric.sdk.android.Fabric
|
||||
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
|
||||
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
|
||||
import java.net.UnknownHostException
|
||||
|
||||
fun initCrashlytics(context: Context, appInfo: AppInfo) {
|
||||
Fabric.with(Fabric.Builder(context)
|
||||
@ -21,6 +24,13 @@ fun initCrashlytics(context: Context, appInfo: AppInfo) {
|
||||
.build())
|
||||
}
|
||||
|
||||
class CrashlyticsTree : CrashlyticsLogTree(Log.VERBOSE)
|
||||
class CrashlyticsTree : CrashlyticsLogTree(Log.VERBOSE) {
|
||||
|
||||
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
||||
if (t is FeatureDisabledException || t is FeatureNotAvailableException || t is UnknownHostException) return
|
||||
|
||||
super.log(priority, tag, message, t)
|
||||
}
|
||||
}
|
||||
|
||||
class CrashlyticsExceptionTree : CrashlyticsLogExceptionTree()
|
||||
|
@ -8,6 +8,7 @@ import io.github.wulkanowy.data.repositories.createSemesterEntity
|
||||
import io.reactivex.Maybe
|
||||
import io.reactivex.Single
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNotEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
@ -37,13 +38,14 @@ class SemesterRepositoryTest {
|
||||
fun initTest() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
semesterRepository = SemesterRepository(semesterRemote, semesterLocal, settings)
|
||||
doReturn("SCRAPPER").`when`(student).loginMode
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getSemesters_noSemesters() {
|
||||
val semesters = listOf(
|
||||
createSemesterEntity(0, 0, now().minusMonths(6), now().minusMonths(3)),
|
||||
createSemesterEntity(0, 0, now().minusMonths(3), now())
|
||||
createSemesterEntity(1, 1, now().minusMonths(6), now().minusMonths(3)),
|
||||
createSemesterEntity(1, 2, now().minusMonths(3), now())
|
||||
)
|
||||
|
||||
doReturn(Maybe.empty<Semester>()).`when`(semesterLocal).getSemesters(student)
|
||||
@ -55,11 +57,47 @@ class SemesterRepositoryTest {
|
||||
verify(semesterLocal).saveSemesters(semesters)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getSemesters_invalidDiary_api() {
|
||||
doReturn("API").`when`(student).loginMode
|
||||
val badSemesters = listOf(
|
||||
createSemesterEntity(0, 1, now().minusMonths(6), now().minusMonths(3)),
|
||||
createSemesterEntity(0, 2, now().minusMonths(3), now())
|
||||
)
|
||||
|
||||
doReturn(Maybe.just(badSemesters)).`when`(semesterLocal).getSemesters(student)
|
||||
|
||||
val items = semesterRepository.getSemesters(student).blockingGet()
|
||||
assertEquals(2, items.size)
|
||||
assertEquals(0, items[0].diaryId)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getSemesters_invalidDiary_scrapper() {
|
||||
doReturn("SCRAPPER").`when`(student).loginMode
|
||||
val badSemesters = listOf(
|
||||
createSemesterEntity(0, 1, now().minusMonths(6), now().minusMonths(3)),
|
||||
createSemesterEntity(0, 2, now().minusMonths(3), now())
|
||||
)
|
||||
|
||||
val goodSemesters = listOf(
|
||||
createSemesterEntity(1, 1, now().minusMonths(6), now().minusMonths(3)),
|
||||
createSemesterEntity(1, 2, now().minusMonths(3), now())
|
||||
)
|
||||
|
||||
doReturn(Maybe.just(badSemesters), Maybe.just(badSemesters), Maybe.just(goodSemesters)).`when`(semesterLocal).getSemesters(student)
|
||||
doReturn(Single.just(goodSemesters)).`when`(semesterRemote).getSemesters(student)
|
||||
|
||||
val items = semesterRepository.getSemesters(student).blockingGet()
|
||||
assertEquals(2, items.size)
|
||||
assertNotEquals(0, items[0].diaryId)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getSemesters_noCurrent() {
|
||||
val semesters = listOf(
|
||||
createSemesterEntity(0, 0, now().minusMonths(12), now().minusMonths(6)),
|
||||
createSemesterEntity(0, 0, now().minusMonths(6), now().minusMonths(1))
|
||||
createSemesterEntity(1, 1, now().minusMonths(12), now().minusMonths(6)),
|
||||
createSemesterEntity(1, 2, now().minusMonths(6), now().minusMonths(1))
|
||||
)
|
||||
|
||||
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)
|
||||
@ -71,8 +109,8 @@ class SemesterRepositoryTest {
|
||||
@Test
|
||||
fun getSemesters_oneCurrent() {
|
||||
val semesters = listOf(
|
||||
createSemesterEntity(0, 0, now().minusMonths(6), now().minusMonths(3)),
|
||||
createSemesterEntity(0, 0, now().minusMonths(3), now())
|
||||
createSemesterEntity(1, 1, now().minusMonths(6), now().minusMonths(3)),
|
||||
createSemesterEntity(1, 2, now().minusMonths(3), now())
|
||||
)
|
||||
|
||||
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)
|
||||
@ -84,8 +122,8 @@ class SemesterRepositoryTest {
|
||||
@Test
|
||||
fun getSemesters_doubleCurrent() {
|
||||
val semesters = listOf(
|
||||
createSemesterEntity(0, 0, now(), now()),
|
||||
createSemesterEntity(0, 0, now(), now())
|
||||
createSemesterEntity(1, 1, now(), now()),
|
||||
createSemesterEntity(1, 2, now(), now())
|
||||
)
|
||||
|
||||
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)
|
||||
@ -97,8 +135,8 @@ class SemesterRepositoryTest {
|
||||
@Test
|
||||
fun getSemesters_noSemesters_refreshOnNoCurrent() {
|
||||
val semesters = listOf(
|
||||
createSemesterEntity(0, 0, now().minusMonths(6), now().minusMonths(3)),
|
||||
createSemesterEntity(0, 0, now().minusMonths(3), now())
|
||||
createSemesterEntity(1, 1, now().minusMonths(6), now().minusMonths(3)),
|
||||
createSemesterEntity(1, 2, now().minusMonths(3), now())
|
||||
)
|
||||
|
||||
doReturn(Maybe.empty<Semester>()).`when`(semesterLocal).getSemesters(student)
|
||||
@ -113,8 +151,8 @@ class SemesterRepositoryTest {
|
||||
@Test
|
||||
fun getSemesters_noCurrent_refreshOnNoCurrent() {
|
||||
val semesters = listOf(
|
||||
createSemesterEntity(0, 0, now().minusMonths(12), now().minusMonths(6)),
|
||||
createSemesterEntity(0, 0, now().minusMonths(6), now().minusMonths(1))
|
||||
createSemesterEntity(1, 1, now().minusMonths(12), now().minusMonths(6)),
|
||||
createSemesterEntity(1, 2, now().minusMonths(6), now().minusMonths(1))
|
||||
)
|
||||
|
||||
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)
|
||||
@ -127,8 +165,8 @@ class SemesterRepositoryTest {
|
||||
@Test
|
||||
fun getSemesters_doubleCurrent_refreshOnNoCurrent() {
|
||||
val semesters = listOf(
|
||||
createSemesterEntity(0, 0, now(), now()),
|
||||
createSemesterEntity(0, 0, now(), now())
|
||||
createSemesterEntity(1, 1, now(), now()),
|
||||
createSemesterEntity(1, 2, now(), now())
|
||||
)
|
||||
|
||||
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)
|
||||
@ -140,8 +178,8 @@ class SemesterRepositoryTest {
|
||||
@Test(expected = IllegalArgumentException::class)
|
||||
fun getCurrentSemester_doubleCurrent() {
|
||||
val semesters = listOf(
|
||||
createSemesterEntity(0, 0, now(), now()),
|
||||
createSemesterEntity(0, 0, now(), now())
|
||||
createSemesterEntity(1, 1, now(), now()),
|
||||
createSemesterEntity(1, 1, now(), now())
|
||||
)
|
||||
|
||||
doReturn(Maybe.just(semesters)).`when`(semesterLocal).getSemesters(student)
|
||||
|
@ -1,5 +1,5 @@
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.71'
|
||||
ext.kotlin_version = '1.3.72'
|
||||
ext.about_libraries = '8.1.1'
|
||||
repositories {
|
||||
mavenCentral()
|
||||
@ -10,7 +10,7 @@ buildscript {
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath 'com.android.tools.build:gradle:3.6.2'
|
||||
classpath 'com.android.tools.build:gradle:3.6.3'
|
||||
classpath 'com.google.gms:google-services:4.3.3'
|
||||
//noinspection GradleDependency https://github.com/firebase/firebase-android-sdk/issues/1276#issuecomment-592098283
|
||||
classpath "io.fabric.tools:gradle:1.31.0"
|
||||
|
Loading…
x
Reference in New Issue
Block a user