forked from github/wulkanowy-mirror
Merge branch 'release/2.0.1'
This commit is contained in:
commit
9697a39464
@ -23,8 +23,8 @@ android {
|
||||
testApplicationId "io.github.tests.wulkanowy"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 33
|
||||
versionCode 122
|
||||
versionName "2.0.0"
|
||||
versionCode 123
|
||||
versionName "2.0.1"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
resValue "string", "app_name", "Wulkanowy"
|
||||
@ -161,7 +161,7 @@ play {
|
||||
defaultToAppBundles = false
|
||||
track = 'production'
|
||||
releaseStatus = com.github.triplet.gradle.androidpublisher.ReleaseStatus.IN_PROGRESS
|
||||
userFraction = 0.50d
|
||||
userFraction = 0.10d
|
||||
updatePriority = 2
|
||||
enabled.set(false)
|
||||
}
|
||||
@ -186,7 +186,7 @@ ext {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "io.github.wulkanowy:sdk:2.0.0"
|
||||
implementation 'io.github.wulkanowy:sdk:2.0.1'
|
||||
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
|
||||
|
||||
|
@ -2,6 +2,7 @@ package io.github.wulkanowy.data.db.dao
|
||||
|
||||
import androidx.room.*
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.db.entities.StudentName
|
||||
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
|
||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||
import javax.inject.Singleton
|
||||
@ -19,6 +20,9 @@ abstract class StudentDao {
|
||||
@Update(entity = Student::class)
|
||||
abstract suspend fun update(studentNickAndAvatar: StudentNickAndAvatar)
|
||||
|
||||
@Update(entity = Student::class)
|
||||
abstract suspend fun update(studentName: StudentName)
|
||||
|
||||
@Query("SELECT * FROM Students WHERE is_current = 1")
|
||||
abstract suspend fun loadCurrent(): Student?
|
||||
|
||||
|
@ -0,0 +1,18 @@
|
||||
package io.github.wulkanowy.data.db.entities
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import java.io.Serializable
|
||||
|
||||
@Entity
|
||||
data class StudentName(
|
||||
|
||||
@ColumnInfo(name = "student_name")
|
||||
val studentName: String
|
||||
|
||||
) : Serializable {
|
||||
|
||||
@PrimaryKey
|
||||
var id: Long = 0
|
||||
}
|
@ -6,7 +6,9 @@ import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import io.github.wulkanowy.data.db.AppDatabase
|
||||
import io.github.wulkanowy.data.db.dao.SemesterDao
|
||||
import io.github.wulkanowy.data.db.dao.StudentDao
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.db.entities.StudentName
|
||||
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
|
||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
|
||||
@ -14,6 +16,7 @@ import io.github.wulkanowy.data.mappers.mapToPojo
|
||||
import io.github.wulkanowy.data.pojos.RegisterUser
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.DispatchersProvider
|
||||
import io.github.wulkanowy.utils.init
|
||||
import io.github.wulkanowy.utils.security.decrypt
|
||||
import io.github.wulkanowy.utils.security.encrypt
|
||||
import kotlinx.coroutines.withContext
|
||||
@ -146,4 +149,21 @@ class StudentRepository @Inject constructor(
|
||||
|
||||
suspend fun isOneUniqueStudent() = getSavedStudents(false)
|
||||
.distinctBy { it.student.studentName }.size == 1
|
||||
|
||||
suspend fun authorizePermission(student: Student, semester: Semester, pesel: String) =
|
||||
sdk.init(student)
|
||||
.switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear)
|
||||
.authorizePermission(pesel)
|
||||
|
||||
suspend fun refreshStudentName(student: Student, semester: Semester) {
|
||||
val newCurrentApiStudent = sdk.init(student)
|
||||
.switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear)
|
||||
.getCurrentStudent() ?: return
|
||||
|
||||
val studentName = StudentName(
|
||||
studentName = "${newCurrentApiStudent.studentName} ${newCurrentApiStudent.studentSurname}"
|
||||
).apply { id = student.id }
|
||||
|
||||
studentDb.update(studentName)
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.snackbar.Snackbar.LENGTH_LONG
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.ui.modules.auth.AuthDialog
|
||||
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
||||
import io.github.wulkanowy.utils.FragmentLifecycleLogger
|
||||
import io.github.wulkanowy.utils.getThemeAttrColor
|
||||
@ -76,6 +77,10 @@ abstract class BaseActivity<T : BasePresenter<out BaseView>, VB : ViewBinding> :
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun showAuthDialog() {
|
||||
AuthDialog.newInstance().show(supportFragmentManager, "auth_dialog")
|
||||
}
|
||||
|
||||
override fun showChangePasswordSnackbar(redirectUrl: String) {
|
||||
messageContainer?.let {
|
||||
Snackbar.make(it, R.string.error_password_change_required, LENGTH_LONG)
|
||||
|
@ -5,10 +5,10 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.google.android.material.elevation.SurfaceColors
|
||||
import io.github.wulkanowy.ui.modules.auth.AuthDialog
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.lifecycleAwareVariable
|
||||
import javax.inject.Inject
|
||||
@ -40,17 +40,19 @@ abstract class BaseDialogFragment<VB : ViewBinding> : DialogFragment(), BaseView
|
||||
(activity as? BaseActivity<*, *>)?.showChangePasswordSnackbar(redirectUrl)
|
||||
}
|
||||
|
||||
override fun showAuthDialog() {
|
||||
AuthDialog.newInstance().show(childFragmentManager, "auth_dialog")
|
||||
}
|
||||
|
||||
override fun showErrorDetailsDialog(error: Throwable) {
|
||||
ErrorDialog.newInstance(error).show(childFragmentManager, error.toString())
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
view.setBackgroundColor(SurfaceColors.SURFACE_3.getColor(requireContext()))
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
|
@ -7,6 +7,7 @@ import androidx.viewbinding.ViewBinding
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.snackbar.Snackbar.LENGTH_LONG
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.ui.modules.auth.AuthDialog
|
||||
import io.github.wulkanowy.utils.lifecycleAwareVariable
|
||||
|
||||
abstract class BaseFragment<VB : ViewBinding>(@LayoutRes layoutId: Int) : Fragment(layoutId),
|
||||
@ -42,6 +43,10 @@ abstract class BaseFragment<VB : ViewBinding>(@LayoutRes layoutId: Int) : Fragme
|
||||
(activity as? BaseActivity<*, *>)?.showExpiredDialog()
|
||||
}
|
||||
|
||||
override fun showAuthDialog() {
|
||||
AuthDialog.newInstance().show(childFragmentManager, "auth_dialog")
|
||||
}
|
||||
|
||||
override fun openClearLoginView() {
|
||||
(activity as? BaseActivity<*, *>)?.openClearLoginView()
|
||||
}
|
||||
|
@ -1,10 +1,15 @@
|
||||
package io.github.wulkanowy.ui.base
|
||||
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
open class BasePresenter<T : BaseView>(
|
||||
@ -26,6 +31,7 @@ open class BasePresenter<T : BaseView>(
|
||||
onSessionExpired = view::showExpiredDialog
|
||||
onNoCurrentStudent = view::openClearLoginView
|
||||
onPasswordChangeRequired = view::showChangePasswordSnackbar
|
||||
onAuthorizationRequired = view::showAuthDialog
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,8 @@ interface BaseView {
|
||||
|
||||
fun showExpiredDialog()
|
||||
|
||||
fun showAuthDialog()
|
||||
|
||||
fun openClearLoginView()
|
||||
|
||||
fun showErrorDetailsDialog(error: Throwable)
|
||||
|
@ -3,6 +3,7 @@ package io.github.wulkanowy.ui.base
|
||||
import android.content.Context
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
|
||||
import io.github.wulkanowy.sdk.scrapper.exception.AuthorizationRequiredException
|
||||
import io.github.wulkanowy.sdk.scrapper.login.BadCredentialsException
|
||||
import io.github.wulkanowy.sdk.scrapper.login.PasswordChangeRequiredException
|
||||
import io.github.wulkanowy.utils.getErrorString
|
||||
@ -20,6 +21,8 @@ open class ErrorHandler @Inject constructor(@ApplicationContext protected val co
|
||||
|
||||
var onPasswordChangeRequired: (String) -> Unit = {}
|
||||
|
||||
var onAuthorizationRequired: () -> Unit = {}
|
||||
|
||||
fun dispatch(error: Throwable) {
|
||||
Timber.e(error, "An exception occurred while the Wulkanowy was running")
|
||||
proceed(error)
|
||||
@ -31,6 +34,7 @@ open class ErrorHandler @Inject constructor(@ApplicationContext protected val co
|
||||
is PasswordChangeRequiredException -> onPasswordChangeRequired(error.redirectUrl)
|
||||
is ScramblerException, is BadCredentialsException -> onSessionExpired()
|
||||
is NoCurrentStudentException -> onNoCurrentStudent()
|
||||
is AuthorizationRequiredException -> onAuthorizationRequired()
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,5 +43,6 @@ open class ErrorHandler @Inject constructor(@ApplicationContext protected val co
|
||||
onSessionExpired = {}
|
||||
onNoCurrentStudent = {}
|
||||
onPasswordChangeRequired = {}
|
||||
onAuthorizationRequired = {}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,81 @@
|
||||
package io.github.wulkanowy.ui.modules.auth
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.text.parseAsHtml
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.databinding.DialogAuthBinding
|
||||
import io.github.wulkanowy.ui.base.BaseDialogFragment
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class AuthDialog : BaseDialogFragment<DialogAuthBinding>(), AuthView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: AuthPresenter
|
||||
|
||||
companion object {
|
||||
fun newInstance() = AuthDialog()
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setStyle(STYLE_NO_TITLE, R.style.FullScreenDialogStyle)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
return DialogAuthBinding.inflate(inflater).apply { binding = this }.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
presenter.onAttachView(this)
|
||||
|
||||
binding.authInput.doOnTextChanged { text, _, _, _ ->
|
||||
presenter.onPeselChange(text?.toString())
|
||||
}
|
||||
|
||||
binding.authButton.setOnClickListener { presenter.authorize() }
|
||||
binding.authSuccessButton.setOnClickListener {
|
||||
activity?.recreate()
|
||||
dismiss()
|
||||
}
|
||||
binding.authButtonSkip.setOnClickListener { dismiss() }
|
||||
}
|
||||
|
||||
override fun enableAuthButton(isEnabled: Boolean) {
|
||||
binding.authButton.isEnabled = isEnabled
|
||||
}
|
||||
|
||||
override fun showProgress(show: Boolean) {
|
||||
binding.authProgress.isVisible = show
|
||||
}
|
||||
|
||||
override fun showPeselError(show: Boolean) {
|
||||
binding.authInputLayout.error = getString(R.string.auth_api_error).takeIf { show }
|
||||
}
|
||||
|
||||
override fun showInvalidPeselError(show: Boolean) {
|
||||
binding.authInputLayout.error = getString(R.string.auth_invalid_error).takeIf { show }
|
||||
}
|
||||
|
||||
override fun showSuccess(show: Boolean) {
|
||||
binding.authSuccess.isVisible = show
|
||||
}
|
||||
|
||||
override fun showContent(show: Boolean) {
|
||||
binding.authForm.isVisible = show
|
||||
}
|
||||
|
||||
override fun showDescriptionWithName(name: String) {
|
||||
binding.authDescription.text = getString(R.string.auth_description, name).parseAsHtml()
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
package io.github.wulkanowy.ui.modules.auth
|
||||
|
||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class AuthPresenter @Inject constructor(
|
||||
private val semesterRepository: SemesterRepository,
|
||||
errorHandler: ErrorHandler,
|
||||
studentRepository: StudentRepository
|
||||
) : BasePresenter<AuthView>(errorHandler, studentRepository) {
|
||||
|
||||
private var pesel: String = ""
|
||||
|
||||
override fun onAttachView(view: AuthView) {
|
||||
super.onAttachView(view)
|
||||
view.enableAuthButton(pesel.length == 11)
|
||||
view.showSuccess(false)
|
||||
view.showProgress(false)
|
||||
|
||||
loadName()
|
||||
}
|
||||
|
||||
private fun loadName() {
|
||||
presenterScope.launch {
|
||||
runCatching { studentRepository.getCurrentStudent(false) }
|
||||
.onSuccess { view?.showDescriptionWithName(it.studentName) }
|
||||
.onFailure { errorHandler.dispatch(it) }
|
||||
}
|
||||
}
|
||||
|
||||
fun onPeselChange(newPesel: String?) {
|
||||
pesel = newPesel.orEmpty()
|
||||
|
||||
view?.enableAuthButton(pesel.length == 11)
|
||||
view?.showPeselError(false)
|
||||
view?.showInvalidPeselError(false)
|
||||
}
|
||||
|
||||
fun authorize() {
|
||||
presenterScope.launch {
|
||||
view?.showProgress(true)
|
||||
view?.showContent(false)
|
||||
|
||||
if (!isValidPESEL(pesel)) {
|
||||
view?.showInvalidPeselError(true)
|
||||
view?.showProgress(false)
|
||||
view?.showContent(true)
|
||||
return@launch
|
||||
}
|
||||
|
||||
runCatching {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
|
||||
val isSuccess = studentRepository.authorizePermission(student, semester, pesel)
|
||||
if (isSuccess) {
|
||||
studentRepository.refreshStudentName(student, semester)
|
||||
}
|
||||
isSuccess
|
||||
}
|
||||
.onFailure { errorHandler.dispatch(it) }
|
||||
.onSuccess {
|
||||
if (it) {
|
||||
view?.showSuccess(true)
|
||||
view?.showContent(false)
|
||||
view?.showPeselError(false)
|
||||
} else {
|
||||
view?.showSuccess(false)
|
||||
view?.showContent(true)
|
||||
view?.showPeselError(true)
|
||||
}
|
||||
}
|
||||
|
||||
view?.showProgress(false)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isValidPESEL(peselString: String): Boolean {
|
||||
if (peselString.length != 11) {
|
||||
return false
|
||||
}
|
||||
|
||||
val weights = intArrayOf(1, 3, 7, 9, 1, 3, 7, 9, 1, 3)
|
||||
var sum = 0
|
||||
|
||||
for (i in 0 until 10) {
|
||||
sum += weights[i] * Character.getNumericValue(peselString[i])
|
||||
}
|
||||
|
||||
sum %= 10
|
||||
sum = 10 - sum
|
||||
sum %= 10
|
||||
|
||||
return sum == Character.getNumericValue(peselString[10])
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package io.github.wulkanowy.ui.modules.auth
|
||||
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface AuthView : BaseView {
|
||||
|
||||
fun enableAuthButton(isEnabled: Boolean)
|
||||
|
||||
fun showProgress(show: Boolean)
|
||||
|
||||
fun showPeselError(show: Boolean)
|
||||
|
||||
fun showInvalidPeselError(show: Boolean)
|
||||
|
||||
fun showSuccess(show: Boolean)
|
||||
|
||||
fun showContent(show: Boolean)
|
||||
|
||||
fun showDescriptionWithName(name: String)
|
||||
}
|
@ -142,10 +142,15 @@ class SendMessageActivity : BaseActivity<SendMessagePresenter, ActivitySendMessa
|
||||
|
||||
private fun initializeMessageContainer() {
|
||||
ViewCompat.setOnApplyWindowInsetsListener(binding.sendMessageScroll) { view, insets ->
|
||||
val bottomInsets = insets.getInsets(WindowInsetsCompat.Type.navigationBars())
|
||||
val navigationBarInsets = insets.getInsets(WindowInsetsCompat.Type.navigationBars())
|
||||
val imeInsets = insets.getInsets(WindowInsetsCompat.Type.ime())
|
||||
|
||||
view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
bottomMargin = bottomInsets.bottom
|
||||
bottomMargin = if (imeInsets.bottom > navigationBarInsets.bottom) {
|
||||
imeInsets.bottom
|
||||
} else {
|
||||
navigationBarInsets.bottom
|
||||
}
|
||||
}
|
||||
WindowInsetsCompat.CONSUMED
|
||||
}
|
||||
|
@ -31,4 +31,6 @@ class SettingsFragment : PreferenceFragmentCompat(), MainView.TitledView, Settin
|
||||
override fun showErrorDetailsDialog(error: Throwable) {}
|
||||
|
||||
override fun showChangePasswordSnackbar(redirectUrl: String) {}
|
||||
|
||||
override fun showAuthDialog() {}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.ui.base.BaseActivity
|
||||
import io.github.wulkanowy.ui.base.ErrorDialog
|
||||
import io.github.wulkanowy.ui.modules.auth.AuthDialog
|
||||
import io.github.wulkanowy.ui.modules.main.MainView
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
import javax.inject.Inject
|
||||
@ -62,6 +63,10 @@ class AdvancedFragment : PreferenceFragmentCompat(),
|
||||
ErrorDialog.newInstance(error).show(childFragmentManager, error.toString())
|
||||
}
|
||||
|
||||
override fun showAuthDialog() {
|
||||
AuthDialog.newInstance().show(childFragmentManager, "auth_dialog")
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
preferenceScreen.sharedPreferences?.registerOnSharedPreferenceChangeListener(this)
|
||||
|
@ -9,6 +9,7 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.ui.base.BaseActivity
|
||||
import io.github.wulkanowy.ui.base.ErrorDialog
|
||||
import io.github.wulkanowy.ui.modules.auth.AuthDialog
|
||||
import io.github.wulkanowy.ui.modules.main.MainView
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
import javax.inject.Inject
|
||||
@ -78,6 +79,10 @@ class AppearanceFragment : PreferenceFragmentCompat(),
|
||||
ErrorDialog.newInstance(error).show(childFragmentManager, error.toString())
|
||||
}
|
||||
|
||||
override fun showAuthDialog() {
|
||||
AuthDialog.newInstance().show(childFragmentManager, "auth_dialog")
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
preferenceScreen.sharedPreferences?.registerOnSharedPreferenceChangeListener(this)
|
||||
|
@ -21,6 +21,7 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.ui.base.BaseActivity
|
||||
import io.github.wulkanowy.ui.base.ErrorDialog
|
||||
import io.github.wulkanowy.ui.modules.auth.AuthDialog
|
||||
import io.github.wulkanowy.ui.modules.main.MainView
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
import io.github.wulkanowy.utils.openInternetBrowser
|
||||
@ -148,6 +149,10 @@ class NotificationsFragment : PreferenceFragmentCompat(),
|
||||
ErrorDialog.newInstance(error).show(childFragmentManager, error.toString())
|
||||
}
|
||||
|
||||
override fun showAuthDialog() {
|
||||
AuthDialog.newInstance().show(childFragmentManager, "auth_dialog")
|
||||
}
|
||||
|
||||
override fun showFixSyncDialog() {
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.pref_notify_fix_sync_issues)
|
||||
|
@ -10,6 +10,7 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.ui.base.BaseActivity
|
||||
import io.github.wulkanowy.ui.base.ErrorDialog
|
||||
import io.github.wulkanowy.ui.modules.auth.AuthDialog
|
||||
import io.github.wulkanowy.ui.modules.main.MainView
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -99,6 +100,10 @@ class SyncFragment : PreferenceFragmentCompat(),
|
||||
ErrorDialog.newInstance(error).show(childFragmentManager, "error_details")
|
||||
}
|
||||
|
||||
override fun showAuthDialog() {
|
||||
AuthDialog.newInstance().show(childFragmentManager, "auth_dialog")
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
preferenceScreen.sharedPreferences?.registerOnSharedPreferenceChangeListener(this)
|
||||
|
@ -2,4 +2,4 @@ package io.github.wulkanowy.utils
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
|
||||
inline val Student.nickOrName get() = if (nick.isBlank()) studentName else nick
|
||||
inline val Student.nickOrName get() = nick.ifBlank { studentName }
|
||||
|
@ -4,5 +4,6 @@ Wersja 2.0.0
|
||||
— dodaliśmy możliwość zmiany kolejności pozycji w menu dolnym
|
||||
— poprawiliśmy sposób wyświetlania błędu o nieprawidłowym haśle na ekranie logowania
|
||||
— od teraz zmiana ustawień liczenia średniej automatycznie odświeży listę ocen
|
||||
— dodaliśmy okienko na wpisanie numeru PESEL, gdy dziennik wymaga dodatkowej autoryzacji dostępu
|
||||
|
||||
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
|
||||
|
10
app/src/main/res/drawable/ic_auth_success.xml
Normal file
10
app/src/main/res/drawable/ic_auth_success.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<vector android:height="24dp"
|
||||
android:tint="#000000"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
android:width="24dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM16.59,7.58L10,14.17l-2.59,-2.58L6,13l4,4 8,-8z" />
|
||||
</vector>
|
@ -22,17 +22,15 @@
|
||||
|
||||
<io.github.wulkanowy.materialchipsinput.ConsumedNestedScrollView
|
||||
android:id="@+id/sendMessageScroll"
|
||||
android:layout_width="0dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:fillViewport="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/send_app_bar">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/sendMessageContent"
|
||||
|
128
app/src/main/res/layout/dialog_auth.xml
Normal file
128
app/src/main/res/layout/dialog_auth.xml
Normal file
@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView 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="match_parent"
|
||||
android:fillViewport="true">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/auth_form"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/auth_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:text="@string/auth_title"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/auth_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintTop_toBottomOf="@id/auth_title"
|
||||
app:lineHeight="24sp"
|
||||
tools:text="@string/auth_description" />
|
||||
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/auth_input_layout"
|
||||
style="@style/Widget.Material3.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginTop="24dp"
|
||||
android:hint="@string/auth_pesel"
|
||||
app:errorEnabled="true"
|
||||
app:layout_constraintTop_toBottomOf="@id/auth_description">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/auth_input"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="numberDecimal"
|
||||
android:maxLength="11" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/auth_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/auth_button"
|
||||
app:layout_constraintBottom_toTopOf="@id/auth_button_skip"
|
||||
app:layout_constraintTop_toBottomOf="@id/auth_input_layout"
|
||||
app:layout_constraintVertical_bias="1" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/auth_button_skip"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="24dp"
|
||||
android:text="@string/auth_button_skip"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/auth_success"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/auth_success_icon"
|
||||
android:layout_width="62dp"
|
||||
android:layout_height="62dp"
|
||||
android:layout_marginTop="220dp"
|
||||
android:importantForAccessibility="no"
|
||||
android:src="@drawable/ic_auth_success"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tint="?colorOnBackground" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/auth_success_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginTop="24dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/auth_success"
|
||||
android:textSize="24sp"
|
||||
app:layout_constraintTop_toBottomOf="@id/auth_success_icon"
|
||||
app:lineHeight="32sp" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/auth_success_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="24dp"
|
||||
android:text="@android:string/ok"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/auth_success_description"
|
||||
app:layout_constraintVertical_bias="1" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/auth_progress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center" />
|
||||
</FrameLayout>
|
||||
</ScrollView>
|
@ -808,6 +808,17 @@
|
||||
<string name="menu_order_confirm_restart">Restart</string>
|
||||
|
||||
|
||||
<!--Auth-->
|
||||
<string name="auth_api_error">Authorization has been rejected. The data provided does not match the records in the secretary\'s office.</string>
|
||||
<string name="auth_invalid_error">Invalid PESEL</string>
|
||||
<string name="auth_pesel">PESEL</string>
|
||||
<string name="auth_button">Authorize</string>
|
||||
<string name="auth_success">Authorization completed successfully</string>
|
||||
<string name="auth_title">Authorization</string>
|
||||
<string name="auth_description">To operate the application, we need to confirm your identity. Please enter the student\'s PESEL <b>%1$s</b> in the field below</string>
|
||||
<string name="auth_button_skip">Skip for now</string>
|
||||
|
||||
|
||||
<!--Errors-->
|
||||
<string name="error_no_internet">No internet connection</string>
|
||||
<string name="error_invalid_device_datetime">An error occurred. Check your device clock</string>
|
||||
|
@ -78,4 +78,9 @@
|
||||
<item name="android:background">@drawable/background_material_alert_dialog</item>
|
||||
<item name="android:layout" tools:ignore="PrivateResource">@layout/m3_alert_dialog</item>
|
||||
</style>
|
||||
|
||||
<style name="FullScreenDialogStyle" parent="WulkanowyTheme">
|
||||
<item name="android:windowFullscreen">true</item>
|
||||
<item name="android:windowIsFloating">false</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
@ -13,6 +13,7 @@ import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.databinding.DialogAdsConsentBinding
|
||||
import io.github.wulkanowy.ui.base.BaseActivity
|
||||
import io.github.wulkanowy.ui.base.ErrorDialog
|
||||
import io.github.wulkanowy.ui.modules.auth.AuthDialog
|
||||
import io.github.wulkanowy.ui.modules.main.MainView
|
||||
import io.github.wulkanowy.utils.openInternetBrowser
|
||||
import javax.inject.Inject
|
||||
@ -146,6 +147,10 @@ class AdsFragment : PreferenceFragmentCompat(), MainView.TitledView, AdsView {
|
||||
(activity as? BaseActivity<*, *>)?.openClearLoginView()
|
||||
}
|
||||
|
||||
override fun showAuthDialog() {
|
||||
AuthDialog.newInstance().show(childFragmentManager, "auth_dialog")
|
||||
}
|
||||
|
||||
override fun showErrorDetailsDialog(error: Throwable) {
|
||||
ErrorDialog.newInstance(error).show(childFragmentManager, error.toString())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user