forked from github/wulkanowy-mirror
Add account recover (#635)
This commit is contained in:
parent
96c1bb4c69
commit
18d6ec6961
3
.idea/codeStyles/Project.xml
generated
3
.idea/codeStyles/Project.xml
generated
@ -1,9 +1,6 @@
|
|||||||
<component name="ProjectCodeStyleConfiguration">
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
<code_scheme name="Project" version="173">
|
<code_scheme name="Project" version="173">
|
||||||
<option name="LINE_SEPARATOR" value=" " />
|
<option name="LINE_SEPARATOR" value=" " />
|
||||||
<AndroidXmlCodeStyleSettings>
|
|
||||||
<option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
|
|
||||||
</AndroidXmlCodeStyleSettings>
|
|
||||||
<JetCodeStyleSettings>
|
<JetCodeStyleSettings>
|
||||||
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||||
<value>
|
<value>
|
||||||
|
@ -122,7 +122,7 @@ configurations.all {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "io.github.wulkanowy:sdk:7e89883"
|
implementation "io.github.wulkanowy:sdk:6789442"
|
||||||
|
|
||||||
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"
|
||||||
@ -173,7 +173,7 @@ dependencies {
|
|||||||
implementation "com.jakewharton.threetenabp:threetenabp:1.2.2"
|
implementation "com.jakewharton.threetenabp:threetenabp:1.2.2"
|
||||||
implementation "com.jakewharton.timber:timber:4.7.1"
|
implementation "com.jakewharton.timber:timber:4.7.1"
|
||||||
implementation "at.favre.lib:slf4j-timber:1.0.1"
|
implementation "at.favre.lib:slf4j-timber:1.0.1"
|
||||||
implementation "fr.bipi.treessence:treessence:0.3.0"
|
implementation "fr.bipi.treessence:treessence:0.3.2"
|
||||||
implementation "com.mikepenz:aboutlibraries-core:7.1.0"
|
implementation "com.mikepenz:aboutlibraries-core:7.1.0"
|
||||||
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
|
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
|
||||||
|
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
package io.github.wulkanowy.data.repositories.recover
|
||||||
|
|
||||||
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
|
import io.reactivex.Single
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class RecoverRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
|
fun getReCaptchaSiteKey(host: String, symbol: String): Single<Pair<String, String>> {
|
||||||
|
return sdk.getPasswordResetCaptchaCode(host, symbol)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sendRecoverRequest(url: String, symbol: String, email: String, reCaptchaResponse: String): Single<String> {
|
||||||
|
return sdk.sendPasswordResetRequest(url, symbol, email, reCaptchaResponse)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
package io.github.wulkanowy.data.repositories.recover
|
||||||
|
|
||||||
|
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
|
||||||
|
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
||||||
|
import io.reactivex.Single
|
||||||
|
import java.net.UnknownHostException
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class RecoverRepository @Inject constructor(private val settings: InternetObservingSettings, private val remote: RecoverRemote) {
|
||||||
|
|
||||||
|
fun getReCaptchaSiteKey(host: String, symbol: String): Single<Pair<String, String>> {
|
||||||
|
return ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
|
||||||
|
if (it) remote.getReCaptchaSiteKey(host, symbol)
|
||||||
|
else Single.error(UnknownHostException())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sendRecoverRequest(url: String, symbol: String, email: String, reCaptchaResponse: String): Single<String> {
|
||||||
|
return ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
|
||||||
|
if (it) remote.sendRecoverRequest(url, symbol, email, reCaptchaResponse)
|
||||||
|
else Single.error(UnknownHostException())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ import io.github.wulkanowy.ui.base.BaseActivity
|
|||||||
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
|
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
|
||||||
import io.github.wulkanowy.ui.modules.login.advanced.LoginAdvancedFragment
|
import io.github.wulkanowy.ui.modules.login.advanced.LoginAdvancedFragment
|
||||||
import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment
|
import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.login.recover.LoginRecoverFragment
|
||||||
import io.github.wulkanowy.ui.modules.login.studentselect.LoginStudentSelectFragment
|
import io.github.wulkanowy.ui.modules.login.studentselect.LoginStudentSelectFragment
|
||||||
import io.github.wulkanowy.ui.modules.login.symbol.LoginSymbolFragment
|
import io.github.wulkanowy.ui.modules.login.symbol.LoginSymbolFragment
|
||||||
import io.github.wulkanowy.utils.setOnSelectPageListener
|
import io.github.wulkanowy.utils.setOnSelectPageListener
|
||||||
@ -52,7 +53,8 @@ class LoginActivity : BaseActivity<LoginPresenter>(), LoginView {
|
|||||||
LoginFormFragment.newInstance(),
|
LoginFormFragment.newInstance(),
|
||||||
LoginSymbolFragment.newInstance(),
|
LoginSymbolFragment.newInstance(),
|
||||||
LoginStudentSelectFragment.newInstance(),
|
LoginStudentSelectFragment.newInstance(),
|
||||||
LoginAdvancedFragment.newInstance()
|
LoginAdvancedFragment.newInstance(),
|
||||||
|
LoginRecoverFragment.newInstance()
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,4 +101,8 @@ class LoginActivity : BaseActivity<LoginPresenter>(), LoginView {
|
|||||||
fun onAdvancedLoginClick() {
|
fun onAdvancedLoginClick() {
|
||||||
presenter.onAdvancedLoginClick()
|
presenter.onAdvancedLoginClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onRecoverClick() {
|
||||||
|
presenter.onRecoverClick()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,5 +43,8 @@ class LoginErrorHandler @Inject constructor(
|
|||||||
super.clear()
|
super.clear()
|
||||||
onBadCredentials = {}
|
onBadCredentials = {}
|
||||||
onStudentDuplicate = {}
|
onStudentDuplicate = {}
|
||||||
|
onInvalidToken = {}
|
||||||
|
onInvalidPin = {}
|
||||||
|
onInvalidSymbol = {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import io.github.wulkanowy.di.scopes.PerFragment
|
|||||||
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
|
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
|
||||||
import io.github.wulkanowy.ui.modules.login.advanced.LoginAdvancedFragment
|
import io.github.wulkanowy.ui.modules.login.advanced.LoginAdvancedFragment
|
||||||
import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment
|
import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.login.recover.LoginRecoverFragment
|
||||||
import io.github.wulkanowy.ui.modules.login.studentselect.LoginStudentSelectFragment
|
import io.github.wulkanowy.ui.modules.login.studentselect.LoginStudentSelectFragment
|
||||||
import io.github.wulkanowy.ui.modules.login.symbol.LoginSymbolFragment
|
import io.github.wulkanowy.ui.modules.login.symbol.LoginSymbolFragment
|
||||||
|
|
||||||
@ -37,4 +38,8 @@ internal abstract class LoginModule {
|
|||||||
@PerFragment
|
@PerFragment
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract fun bindLoginSelectStudentFragment(): LoginStudentSelectFragment
|
abstract fun bindLoginSelectStudentFragment(): LoginStudentSelectFragment
|
||||||
|
|
||||||
|
@PerFragment
|
||||||
|
@ContributesAndroidInjector
|
||||||
|
abstract fun bindLoginRecoverFragment(): LoginRecoverFragment
|
||||||
}
|
}
|
||||||
|
@ -49,11 +49,15 @@ class LoginPresenter @Inject constructor(
|
|||||||
view?.switchView(3)
|
view?.switchView(3)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onRecoverClick() {
|
||||||
|
view?.switchView(4)
|
||||||
|
}
|
||||||
|
|
||||||
fun onViewSelected(index: Int) {
|
fun onViewSelected(index: Int) {
|
||||||
view?.apply {
|
view?.apply {
|
||||||
when (index) {
|
when (index) {
|
||||||
0 -> showActionBar(false)
|
0 -> showActionBar(false)
|
||||||
1, 2 -> showActionBar(true)
|
1, 2, 3, 4 -> showActionBar(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,7 +66,7 @@ class LoginPresenter @Inject constructor(
|
|||||||
Timber.i("Back pressed in login view")
|
Timber.i("Back pressed in login view")
|
||||||
view?.apply {
|
view?.apply {
|
||||||
when (currentViewIndex) {
|
when (currentViewIndex) {
|
||||||
1, 2, 3 -> switchView(0)
|
1, 2, 3, 4 -> switchView(0)
|
||||||
else -> default()
|
else -> default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ package io.github.wulkanowy.ui.modules.login.advanced
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.View.GONE
|
||||||
|
import android.view.View.VISIBLE
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.ArrayAdapter
|
||||||
@ -98,8 +100,9 @@ class LoginAdvancedFragment : BaseFragment(), LoginAdvancedView {
|
|||||||
loginFormSymbol.setAdapter(ArrayAdapter(requireContext(), android.R.layout.simple_list_item_1, resources.getStringArray(R.array.symbols_values)))
|
loginFormSymbol.setAdapter(ArrayAdapter(requireContext(), android.R.layout.simple_list_item_1, resources.getStringArray(R.array.symbols_values)))
|
||||||
|
|
||||||
with(loginFormHost) {
|
with(loginFormHost) {
|
||||||
setText(hostKeys.getOrElse(0) { "" })
|
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 (loginFormContainer.visibility == GONE) dismissDropDown() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,30 +215,30 @@ class LoginAdvancedFragment : BaseFragment(), LoginAdvancedView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun showOnlyHybridModeInputs() {
|
override fun showOnlyHybridModeInputs() {
|
||||||
loginFormUsernameLayout.visibility = View.VISIBLE
|
loginFormUsernameLayout.visibility = VISIBLE
|
||||||
loginFormPassLayout.visibility = View.VISIBLE
|
loginFormPassLayout.visibility = VISIBLE
|
||||||
loginFormHostLayout.visibility = View.VISIBLE
|
loginFormHostLayout.visibility = VISIBLE
|
||||||
loginFormPinLayout.visibility = View.GONE
|
loginFormPinLayout.visibility = GONE
|
||||||
loginFormSymbolLayout.visibility = View.VISIBLE
|
loginFormSymbolLayout.visibility = VISIBLE
|
||||||
loginFormTokenLayout.visibility = View.GONE
|
loginFormTokenLayout.visibility = GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showOnlyScrapperModeInputs() {
|
override fun showOnlyScrapperModeInputs() {
|
||||||
loginFormUsernameLayout.visibility = View.VISIBLE
|
loginFormUsernameLayout.visibility = VISIBLE
|
||||||
loginFormPassLayout.visibility = View.VISIBLE
|
loginFormPassLayout.visibility = VISIBLE
|
||||||
loginFormHostLayout.visibility = View.VISIBLE
|
loginFormHostLayout.visibility = VISIBLE
|
||||||
loginFormPinLayout.visibility = View.GONE
|
loginFormPinLayout.visibility = GONE
|
||||||
loginFormSymbolLayout.visibility = View.VISIBLE
|
loginFormSymbolLayout.visibility = VISIBLE
|
||||||
loginFormTokenLayout.visibility = View.GONE
|
loginFormTokenLayout.visibility = GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showOnlyMobileApiModeInputs() {
|
override fun showOnlyMobileApiModeInputs() {
|
||||||
loginFormUsernameLayout.visibility = View.GONE
|
loginFormUsernameLayout.visibility = GONE
|
||||||
loginFormPassLayout.visibility = View.GONE
|
loginFormPassLayout.visibility = GONE
|
||||||
loginFormHostLayout.visibility = View.GONE
|
loginFormHostLayout.visibility = GONE
|
||||||
loginFormPinLayout.visibility = View.VISIBLE
|
loginFormPinLayout.visibility = VISIBLE
|
||||||
loginFormSymbolLayout.visibility = View.VISIBLE
|
loginFormSymbolLayout.visibility = VISIBLE
|
||||||
loginFormTokenLayout.visibility = View.VISIBLE
|
loginFormTokenLayout.visibility = VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showSoftKeyboard() {
|
override fun showSoftKeyboard() {
|
||||||
@ -247,11 +250,11 @@ class LoginAdvancedFragment : BaseFragment(), LoginAdvancedView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun showProgress(show: Boolean) {
|
override fun showProgress(show: Boolean) {
|
||||||
loginFormProgress.visibility = if (show) View.VISIBLE else View.GONE
|
loginFormProgress.visibility = if (show) VISIBLE else GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showContent(show: Boolean) {
|
override fun showContent(show: Boolean) {
|
||||||
loginFormContainer.visibility = if (show) View.VISIBLE else View.GONE
|
loginFormContainer.visibility = if (show) VISIBLE else GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun notifyParentAccountLogged(students: List<Student>) {
|
override fun notifyParentAccountLogged(students: List<Student>) {
|
||||||
|
@ -74,14 +74,15 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
|
|||||||
loginFormPrivacyLink.setOnClickListener { presenter.onPrivacyLinkClick() }
|
loginFormPrivacyLink.setOnClickListener { presenter.onPrivacyLinkClick() }
|
||||||
loginFormFaq.setOnClickListener { presenter.onFaqClick() }
|
loginFormFaq.setOnClickListener { presenter.onFaqClick() }
|
||||||
loginFormContactEmail.setOnClickListener { presenter.onEmailClick() }
|
loginFormContactEmail.setOnClickListener { presenter.onEmailClick() }
|
||||||
|
loginFormRecoverLink.setOnClickListener { presenter.onRecoverClick() }
|
||||||
loginFormPass.setOnEditorActionListener { _, id, _ ->
|
loginFormPass.setOnEditorActionListener { _, id, _ ->
|
||||||
if (id == IME_ACTION_DONE || id == IME_NULL) loginFormSignIn.callOnClick() else false
|
if (id == IME_ACTION_DONE || id == IME_NULL) loginFormSignIn.callOnClick() else false
|
||||||
}
|
}
|
||||||
|
|
||||||
with(loginFormHost) {
|
with(loginFormHost) {
|
||||||
setText(hostKeys.getOrElse(0) { "" })
|
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 (loginFormContainer.visibility == GONE) dismissDropDown() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,6 +168,10 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
|
|||||||
(activity as? LoginActivity)?.onAdvancedLoginClick()
|
(activity as? LoginActivity)?.onAdvancedLoginClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onRecoverClick() {
|
||||||
|
(activity as? LoginActivity)?.onRecoverClick()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
presenter.onDetachView()
|
presenter.onDetachView()
|
||||||
|
@ -108,6 +108,10 @@ class LoginFormPresenter @Inject constructor(
|
|||||||
view?.openEmail()
|
view?.openEmail()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onRecoverClick() {
|
||||||
|
view?.onRecoverClick()
|
||||||
|
}
|
||||||
|
|
||||||
private fun validateCredentials(login: String, password: String): Boolean {
|
private fun validateCredentials(login: String, password: String): Boolean {
|
||||||
var isCorrect = true
|
var isCorrect = true
|
||||||
|
|
||||||
|
@ -54,4 +54,6 @@ interface LoginFormView : BaseView {
|
|||||||
fun openEmail()
|
fun openEmail()
|
||||||
|
|
||||||
fun openAdvancedLogin()
|
fun openAdvancedLogin()
|
||||||
|
|
||||||
|
fun onRecoverClick()
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,209 @@
|
|||||||
|
package io.github.wulkanowy.ui.modules.login.recover
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.View.GONE
|
||||||
|
import android.view.View.VISIBLE
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.webkit.JavascriptInterface
|
||||||
|
import android.webkit.WebView
|
||||||
|
import android.webkit.WebViewClient
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
|
import androidx.core.widget.doOnTextChanged
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
|
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
||||||
|
import io.github.wulkanowy.ui.modules.login.form.LoginSymbolAdapter
|
||||||
|
import io.github.wulkanowy.utils.hideSoftInput
|
||||||
|
import io.github.wulkanowy.utils.showSoftInput
|
||||||
|
import kotlinx.android.synthetic.main.fragment_login_recover.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class LoginRecoverFragment : BaseFragment(), LoginRecoverView {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var presenter: LoginRecoverPresenter
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun newInstance() = LoginRecoverFragment()
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var hostKeys: Array<String>
|
||||||
|
|
||||||
|
private lateinit var hostValues: Array<String>
|
||||||
|
|
||||||
|
override val recoverHostValue: String
|
||||||
|
get() = hostValues.getOrNull(hostKeys.indexOf(loginRecoverHost.text.toString())).orEmpty()
|
||||||
|
|
||||||
|
override val recoverNameValue: String
|
||||||
|
get() = loginRecoverName.text.toString().trim()
|
||||||
|
|
||||||
|
override val recoverSymbolValue: String
|
||||||
|
get() = loginRecoverSymbol.text.toString().trim()
|
||||||
|
|
||||||
|
override val emailHintString: String
|
||||||
|
get() = getString(R.string.login_email_hint)
|
||||||
|
|
||||||
|
override val loginPeselEmailHintString: String
|
||||||
|
get() = getString(R.string.login_login_pesel_email_hint)
|
||||||
|
|
||||||
|
override val invalidEmailString: String
|
||||||
|
get() = getString(R.string.login_invalid_email)
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
return inflater.inflate(R.layout.fragment_login_recover, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
presenter.onAttachView(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initView() {
|
||||||
|
loginRecoverWebView.setBackgroundColor(Color.TRANSPARENT)
|
||||||
|
hostKeys = resources.getStringArray(R.array.hosts_keys)
|
||||||
|
hostValues = resources.getStringArray(R.array.hosts_values)
|
||||||
|
|
||||||
|
loginRecoverName.doOnTextChanged { _, _, _, _ -> presenter.onNameTextChanged() }
|
||||||
|
loginRecoverHost.setOnItemClickListener { _, _, _, _ -> presenter.onHostSelected() }
|
||||||
|
loginRecoverButton.setOnClickListener { presenter.onRecoverClick() }
|
||||||
|
loginRecoverErrorRetry.setOnClickListener { presenter.onRecoverClick() }
|
||||||
|
loginRecoverErrorDetails.setOnClickListener { presenter.onDetailsClick() }
|
||||||
|
loginRecoverLogin.setOnClickListener { (activity as LoginActivity).switchView(0) }
|
||||||
|
|
||||||
|
loginRecoverSymbol.setAdapter(ArrayAdapter(requireContext(), android.R.layout.simple_list_item_1, resources.getStringArray(R.array.symbols_values)))
|
||||||
|
|
||||||
|
with(loginRecoverHost) {
|
||||||
|
setText(hostKeys.getOrNull(0).orEmpty())
|
||||||
|
setAdapter(LoginSymbolAdapter(context, R.layout.support_simple_spinner_dropdown_item, hostKeys))
|
||||||
|
setOnClickListener { if (loginRecoverFormContainer.visibility == GONE) dismissDropDown() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setDefaultCredentials(username: String, symbol: String) {
|
||||||
|
loginRecoverName.setText(username)
|
||||||
|
loginRecoverSymbol.setText(symbol)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setErrorNameRequired() {
|
||||||
|
with(loginRecoverNameLayout) {
|
||||||
|
requestFocus()
|
||||||
|
error = getString(R.string.login_field_required)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setUsernameHint(hint: String) {
|
||||||
|
loginRecoverNameLayout.hint = hint
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setUsernameError(message: String) {
|
||||||
|
with(loginRecoverNameLayout) {
|
||||||
|
requestFocus()
|
||||||
|
error = message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun clearUsernameError() {
|
||||||
|
loginRecoverNameLayout.error = null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showSymbol(show: Boolean) {
|
||||||
|
loginRecoverSymbolLayout.visibility = if (show) VISIBLE else GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showProgress(show: Boolean) {
|
||||||
|
loginRecoverProgress.visibility = if (show) VISIBLE else GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showRecoverForm(show: Boolean) {
|
||||||
|
loginRecoverFormContainer.visibility = if (show) VISIBLE else GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showCaptcha(show: Boolean) {
|
||||||
|
loginRecoverCaptchaContainer.visibility = if (show) VISIBLE else GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showErrorView(show: Boolean) {
|
||||||
|
loginRecoverError.visibility = if (show) VISIBLE else GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setErrorDetails(message: String) {
|
||||||
|
loginRecoverErrorMessage.text = message
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showSuccessView(show: Boolean) {
|
||||||
|
loginRecoverSuccess.visibility = if (show) VISIBLE else GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setSuccessTitle(title: String) {
|
||||||
|
loginRecoverSuccessTitle.text = title
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setSuccessMessage(message: String) {
|
||||||
|
loginRecoverSuccessMessage.text = message
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showSoftKeyboard() {
|
||||||
|
activity?.showSoftInput()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hideSoftKeyboard() {
|
||||||
|
activity?.hideSoftInput()
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetJavaScriptEnabled", "AddJavascriptInterface")
|
||||||
|
override fun loadReCaptcha(siteKey: String, url: String) {
|
||||||
|
val html = """
|
||||||
|
<div style="position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);" id="recaptcha"></div>
|
||||||
|
<script src="https://www.google.com/recaptcha/api.js?onload=cl&render=explicit&hl=pl" async defer></script>
|
||||||
|
<script>var cl=()=>grecaptcha.render("recaptcha",{
|
||||||
|
sitekey:'$siteKey',
|
||||||
|
callback:e =>Android.captchaCallback(e)})</script>
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
with(loginRecoverWebView) {
|
||||||
|
settings.javaScriptEnabled = true
|
||||||
|
webViewClient = object : WebViewClient() {
|
||||||
|
private var recoverWebViewSuccess: Boolean = true
|
||||||
|
|
||||||
|
override fun onPageFinished(view: WebView?, url: String?) {
|
||||||
|
if (recoverWebViewSuccess) {
|
||||||
|
showCaptcha(true)
|
||||||
|
showProgress(false)
|
||||||
|
} else {
|
||||||
|
showProgress(false)
|
||||||
|
showErrorView(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onReceivedError(view: WebView, errorCode: Int, description: String, failingUrl: String) {
|
||||||
|
recoverWebViewSuccess = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loadDataWithBaseURL(url, html, "text/html", "UTF-8", null)
|
||||||
|
addJavascriptInterface(object {
|
||||||
|
@JavascriptInterface
|
||||||
|
fun captchaCallback(reCaptchaResponse: String) {
|
||||||
|
activity?.runOnUiThread {
|
||||||
|
presenter.onReCaptchaVerified(reCaptchaResponse)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, "Android")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
presenter.updateFields()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
loginRecoverWebView.destroy()
|
||||||
|
presenter.onDetachView()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,157 @@
|
|||||||
|
package io.github.wulkanowy.ui.modules.login.recover
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.repositories.recover.RecoverRepository
|
||||||
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
|
import io.github.wulkanowy.utils.ifNullOrBlank
|
||||||
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class LoginRecoverPresenter @Inject constructor(
|
||||||
|
schedulers: SchedulersProvider,
|
||||||
|
studentRepository: StudentRepository,
|
||||||
|
private val loginErrorHandler: RecoverErrorHandler,
|
||||||
|
private val analytics: FirebaseAnalyticsHelper,
|
||||||
|
private val recoverRepository: RecoverRepository
|
||||||
|
) : BasePresenter<LoginRecoverView>(loginErrorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
|
private lateinit var lastError: Throwable
|
||||||
|
|
||||||
|
override fun onAttachView(view: LoginRecoverView) {
|
||||||
|
super.onAttachView(view)
|
||||||
|
view.initView()
|
||||||
|
|
||||||
|
with(loginErrorHandler) {
|
||||||
|
showErrorMessage = ::showErrorMessage
|
||||||
|
onInvalidUsername = ::onInvalidUsername
|
||||||
|
onInvalidCaptcha = ::onInvalidCaptcha
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onNameTextChanged() {
|
||||||
|
view?.clearUsernameError()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onHostSelected() {
|
||||||
|
view?.run {
|
||||||
|
if ("fakelog" in recoverHostValue) setDefaultCredentials("jan@fakelog.cf", "Default")
|
||||||
|
clearUsernameError()
|
||||||
|
updateFields()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateFields() {
|
||||||
|
view?.run {
|
||||||
|
if ("fakelog" in recoverHostValue || "vulcan" in recoverHostValue) {
|
||||||
|
showSymbol(true)
|
||||||
|
setUsernameHint(emailHintString)
|
||||||
|
} else {
|
||||||
|
showSymbol(false)
|
||||||
|
setUsernameHint(loginPeselEmailHintString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onRecoverClick() {
|
||||||
|
val username = view?.recoverNameValue.orEmpty()
|
||||||
|
val host = view?.recoverHostValue.orEmpty()
|
||||||
|
val symbol = view?.recoverSymbolValue.ifNullOrBlank { "Default" }
|
||||||
|
|
||||||
|
if (username.isEmpty()) {
|
||||||
|
view?.setErrorNameRequired()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (("fakelog" in host || "vulcan" in host) && "@" !in username) {
|
||||||
|
view?.setUsernameError(view?.invalidEmailString.orEmpty())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
disposable.add(recoverRepository.getReCaptchaSiteKey(host, symbol)
|
||||||
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
|
.observeOn(schedulers.mainThread)
|
||||||
|
.doOnSubscribe {
|
||||||
|
view?.run {
|
||||||
|
hideSoftKeyboard()
|
||||||
|
showRecoverForm(false)
|
||||||
|
showProgress(true)
|
||||||
|
showErrorView(false)
|
||||||
|
showCaptcha(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.subscribe({ (resetUrl, siteKey) ->
|
||||||
|
view?.loadReCaptcha(siteKey, resetUrl)
|
||||||
|
}) {
|
||||||
|
Timber.e("Obtain captcha site key result: An exception occurred")
|
||||||
|
errorHandler.dispatch(it)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onReCaptchaVerified(reCaptchaResponse: String) {
|
||||||
|
val username = view?.recoverNameValue.orEmpty()
|
||||||
|
val host = view?.recoverHostValue.orEmpty()
|
||||||
|
val symbol = view?.recoverSymbolValue.ifNullOrBlank { "Default" }
|
||||||
|
|
||||||
|
with(disposable) {
|
||||||
|
clear()
|
||||||
|
add(recoverRepository.sendRecoverRequest(host, symbol, username, reCaptchaResponse)
|
||||||
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
|
.observeOn(schedulers.mainThread)
|
||||||
|
.doOnSubscribe {
|
||||||
|
view?.run {
|
||||||
|
showProgress(true)
|
||||||
|
showRecoverForm(false)
|
||||||
|
showCaptcha(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.doFinally {
|
||||||
|
view?.showProgress(false)
|
||||||
|
}
|
||||||
|
.subscribe({
|
||||||
|
view?.run {
|
||||||
|
showSuccessView(true)
|
||||||
|
setSuccessTitle(it.substringBefore(". "))
|
||||||
|
setSuccessMessage(it.substringAfter(". "))
|
||||||
|
}
|
||||||
|
|
||||||
|
analytics.logEvent("account_recover", "register" to host, "symbol" to symbol, "success" to true)
|
||||||
|
}) {
|
||||||
|
Timber.e("Send recover request result: An exception occurred")
|
||||||
|
errorHandler.dispatch(it)
|
||||||
|
analytics.logEvent("account_recover", "register" to host, "symbol" to symbol, "success" to false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onDetailsClick() {
|
||||||
|
view?.showErrorDetailsDialog(lastError)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showErrorMessage(message: String, error: Throwable) {
|
||||||
|
view?.run {
|
||||||
|
lastError = error
|
||||||
|
showProgress(false)
|
||||||
|
setErrorDetails(message)
|
||||||
|
showErrorView(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onInvalidUsername(message: String) {
|
||||||
|
view?.run {
|
||||||
|
setUsernameError(message)
|
||||||
|
showRecoverForm(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onInvalidCaptcha(message: String, error: Throwable) {
|
||||||
|
view?.run {
|
||||||
|
lastError = error
|
||||||
|
setErrorDetails(message)
|
||||||
|
showCaptcha(false)
|
||||||
|
showRecoverForm(false)
|
||||||
|
showErrorView(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package io.github.wulkanowy.ui.modules.login.recover
|
||||||
|
|
||||||
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
|
interface LoginRecoverView : BaseView {
|
||||||
|
|
||||||
|
val recoverHostValue: String
|
||||||
|
|
||||||
|
val recoverNameValue: String
|
||||||
|
|
||||||
|
val recoverSymbolValue: String
|
||||||
|
|
||||||
|
val emailHintString: String
|
||||||
|
|
||||||
|
val loginPeselEmailHintString: String
|
||||||
|
|
||||||
|
val invalidEmailString: String
|
||||||
|
|
||||||
|
fun initView()
|
||||||
|
|
||||||
|
fun setDefaultCredentials(username: String, symbol: String)
|
||||||
|
|
||||||
|
fun clearUsernameError()
|
||||||
|
|
||||||
|
fun showSymbol(show: Boolean)
|
||||||
|
|
||||||
|
fun setErrorNameRequired()
|
||||||
|
|
||||||
|
fun setUsernameHint(hint: String)
|
||||||
|
|
||||||
|
fun setUsernameError(message: String)
|
||||||
|
|
||||||
|
fun showSoftKeyboard()
|
||||||
|
|
||||||
|
fun hideSoftKeyboard()
|
||||||
|
|
||||||
|
fun showProgress(show: Boolean)
|
||||||
|
|
||||||
|
fun showRecoverForm(show: Boolean)
|
||||||
|
|
||||||
|
fun showCaptcha(show: Boolean)
|
||||||
|
|
||||||
|
fun showErrorView(show: Boolean)
|
||||||
|
|
||||||
|
fun setErrorDetails(message: String)
|
||||||
|
|
||||||
|
fun showSuccessView(show: Boolean)
|
||||||
|
|
||||||
|
fun setSuccessMessage(message: String)
|
||||||
|
|
||||||
|
fun setSuccessTitle(title: String)
|
||||||
|
|
||||||
|
fun loadReCaptcha(siteKey: String, url: String)
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package io.github.wulkanowy.ui.modules.login.recover
|
||||||
|
|
||||||
|
import android.content.res.Resources
|
||||||
|
import com.readystatesoftware.chuck.api.ChuckCollector
|
||||||
|
import io.github.wulkanowy.sdk.scrapper.exception.InvalidCaptchaException
|
||||||
|
import io.github.wulkanowy.sdk.scrapper.exception.InvalidEmailException
|
||||||
|
import io.github.wulkanowy.sdk.scrapper.exception.NoAccountFoundException
|
||||||
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class RecoverErrorHandler @Inject constructor(
|
||||||
|
resources: Resources,
|
||||||
|
chuckCollector: ChuckCollector
|
||||||
|
) : ErrorHandler(resources, chuckCollector) {
|
||||||
|
|
||||||
|
var onInvalidUsername: (String) -> Unit = {}
|
||||||
|
|
||||||
|
var onInvalidCaptcha: (String, Throwable) -> Unit = { _, _ -> }
|
||||||
|
|
||||||
|
override fun proceed(error: Throwable) {
|
||||||
|
when (error) {
|
||||||
|
is InvalidEmailException, is NoAccountFoundException -> onInvalidUsername(error.localizedMessage.orEmpty())
|
||||||
|
is InvalidCaptchaException -> onInvalidCaptcha(error.localizedMessage.orEmpty(), error)
|
||||||
|
else -> super.proceed(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun clear() {
|
||||||
|
super.clear()
|
||||||
|
onInvalidUsername = {}
|
||||||
|
}
|
||||||
|
}
|
@ -154,7 +154,7 @@
|
|||||||
android:hint="@string/login_password_hint"
|
android:hint="@string/login_password_hint"
|
||||||
app:errorEnabled="true"
|
app:errorEnabled="true"
|
||||||
app:errorIconDrawable="@null"
|
app:errorIconDrawable="@null"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/loginFormHostLayout"
|
app:layout_constraintBottom_toTopOf="@+id/loginFormRecoverLink"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/loginFormUsernameLayout"
|
app:layout_constraintTop_toBottomOf="@+id/loginFormUsernameLayout"
|
||||||
@ -174,6 +174,22 @@
|
|||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/loginFormRecoverLink"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="24dp"
|
||||||
|
android:layout_marginRight="24dp"
|
||||||
|
android:text="@string/login_recover_button"
|
||||||
|
android:textAppearance="?android:textAppearance"
|
||||||
|
app:backgroundTint="?android:windowBackground"
|
||||||
|
app:fontFamily="sans-serif-medium"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/loginFormHostLayout"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/loginFormPassLayout"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/loginFormHostLayout"
|
android:id="@+id/loginFormHostLayout"
|
||||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||||
@ -181,7 +197,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="24dp"
|
android:layout_marginStart="24dp"
|
||||||
android:layout_marginLeft="24dp"
|
android:layout_marginLeft="24dp"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginEnd="24dp"
|
android:layout_marginEnd="24dp"
|
||||||
android:layout_marginRight="24dp"
|
android:layout_marginRight="24dp"
|
||||||
android:hint="@string/login_host_hint"
|
android:hint="@string/login_host_hint"
|
||||||
@ -189,7 +205,7 @@
|
|||||||
app:layout_constraintBottom_toTopOf="@+id/loginFormSignIn"
|
app:layout_constraintBottom_toTopOf="@+id/loginFormSignIn"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/loginFormPassLayout">
|
app:layout_constraintTop_toBottomOf="@+id/loginFormRecoverLink">
|
||||||
|
|
||||||
<AutoCompleteTextView
|
<AutoCompleteTextView
|
||||||
android:id="@+id/loginFormHost"
|
android:id="@+id/loginFormHost"
|
||||||
|
272
app/src/main/res/layout/fragment_login_recover.xml
Normal file
272
app/src/main/res/layout/fragment_login_recover.xml
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
<FrameLayout 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"
|
||||||
|
tools:context=".ui.modules.login.recover.LoginRecoverFragment">
|
||||||
|
|
||||||
|
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
|
||||||
|
android:id="@+id/loginRecoverProgress"
|
||||||
|
style="@style/Widget.MaterialProgressBar.ProgressBar"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:id="@+id/nestedScrollView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:fillViewport="true"
|
||||||
|
android:scrollbars="none"
|
||||||
|
tools:visibility="invisible">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/loginRecoverFormContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingBottom="16dp"
|
||||||
|
android:visibility="visible">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/loginFormHeader"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="32dp"
|
||||||
|
android:layout_marginLeft="32dp"
|
||||||
|
android:layout_marginTop="48dp"
|
||||||
|
android:layout_marginEnd="32dp"
|
||||||
|
android:layout_marginRight="32dp"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:text="@string/login_recover_title"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:fontFamily="sans-serif-light"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/loginRecoverNameLayout"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_chainStyle="packed" />
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/loginRecoverNameLayout"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="24dp"
|
||||||
|
android:layout_marginLeft="24dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:layout_marginEnd="24dp"
|
||||||
|
android:layout_marginRight="24dp"
|
||||||
|
android:hint="@string/login_email_hint"
|
||||||
|
app:errorEnabled="true"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/loginRecoverHostLayout"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/loginFormHeader">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/loginRecoverName"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:autofillHints="emailAddress"
|
||||||
|
android:inputType="textEmailAddress"
|
||||||
|
android:maxLines="1"
|
||||||
|
tools:targetApi="o" />
|
||||||
|
|
||||||
|
<requestFocus />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/loginRecoverHostLayout"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="24dp"
|
||||||
|
android:layout_marginLeft="24dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginEnd="24dp"
|
||||||
|
android:layout_marginRight="24dp"
|
||||||
|
android:hint="@string/login_host_hint"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/loginRecoverSymbolLayout"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/loginRecoverNameLayout">
|
||||||
|
|
||||||
|
<AutoCompleteTextView
|
||||||
|
android:id="@+id/loginRecoverHost"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:editable="false"
|
||||||
|
tools:ignore="Deprecated,LabelFor" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/loginRecoverSymbolLayout"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="24dp"
|
||||||
|
android:layout_marginLeft="24dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:layout_marginEnd="24dp"
|
||||||
|
android:layout_marginRight="24dp"
|
||||||
|
android:hint="@string/login_symbol_hint_optional"
|
||||||
|
app:errorEnabled="true"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/loginRecoverButton"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/loginRecoverHostLayout">
|
||||||
|
|
||||||
|
<AutoCompleteTextView
|
||||||
|
android:id="@+id/loginRecoverSymbol"
|
||||||
|
style="@style/Widget.MaterialComponents.TextInputEditText.OutlinedBox"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:imeActionLabel="@string/login_sign_in"
|
||||||
|
android:imeOptions="actionDone"
|
||||||
|
android:inputType="textAutoComplete|textNoSuggestions"
|
||||||
|
android:maxLines="1"
|
||||||
|
tools:ignore="LabelFor" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/loginRecoverButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="24dp"
|
||||||
|
android:layout_marginRight="24dp"
|
||||||
|
android:text="@string/login_recover"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/loginRecoverSymbolLayout" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/loginRecoverCaptchaContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<WebView
|
||||||
|
android:id="@+id/loginRecoverWebView"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/loginRecoverError"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="invisible"
|
||||||
|
tools:ignore="UseCompoundDrawables"
|
||||||
|
tools:visibility="invisible">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
app:srcCompat="@drawable/ic_error"
|
||||||
|
app:tint="?colorOnBackground"
|
||||||
|
tools:ignore="contentDescription" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/loginRecoverErrorMessage"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:text="@string/error_unknown"
|
||||||
|
android:textSize="20sp" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/loginRecoverErrorDetails"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
|
android:text="@string/all_details" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/loginRecoverErrorRetry"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/all_retry" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:id="@+id/loginRecoverSuccess"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:fillViewport="true"
|
||||||
|
android:scrollbars="none"
|
||||||
|
android:visibility="invisible"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:ignore="UseCompoundDrawables">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
app:srcCompat="@drawable/ic_all_done"
|
||||||
|
app:tint="?colorOnBackground"
|
||||||
|
tools:ignore="contentDescription" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/loginRecoverSuccessTitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="35dp"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:layout_marginEnd="35dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textSize="20sp"
|
||||||
|
tools:text="Pomyślnie wysłano email!" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/loginRecoverSuccessMessage"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="35dp"
|
||||||
|
android:lineSpacingMultiplier="1.5"
|
||||||
|
android:scrollbars="vertical"
|
||||||
|
android:text="@string/login_recover"
|
||||||
|
android:textSize="14sp"
|
||||||
|
tools:text="@tools:sample/lorem/random" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/loginRecoverLogin"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:layout_marginEnd="30dp"
|
||||||
|
android:layout_marginBottom="30dp"
|
||||||
|
android:text="@android:string/ok" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
</FrameLayout>
|
@ -29,9 +29,11 @@
|
|||||||
<string name="login_header_symbol">Podaj symbol</string>
|
<string name="login_header_symbol">Podaj symbol</string>
|
||||||
<string name="login_nickname_hint">Nazwa użytkownika</string>
|
<string name="login_nickname_hint">Nazwa użytkownika</string>
|
||||||
<string name="login_email_hint">Email</string>
|
<string name="login_email_hint">Email</string>
|
||||||
|
<string name="login_login_pesel_email_hint">Login, PESEL lub e-mail</string>
|
||||||
<string name="login_password_hint">Hasło</string>
|
<string name="login_password_hint">Hasło</string>
|
||||||
<string name="login_host_hint">Dziennik</string>
|
<string name="login_host_hint">Dziennik</string>
|
||||||
<string name="login_symbol_hint">Symbol</string>
|
<string name="login_symbol_hint">Symbol</string>
|
||||||
|
<string name="login_symbol_hint_optional">Symbol (opcjonalnie)</string>
|
||||||
<string name="login_type_api">Mobilne API</string>
|
<string name="login_type_api">Mobilne API</string>
|
||||||
<string name="login_type_scrapper">Scraper</string>
|
<string name="login_type_scrapper">Scraper</string>
|
||||||
<string name="login_type_hybrid">Hybrydowe</string>
|
<string name="login_type_hybrid">Hybrydowe</string>
|
||||||
@ -44,11 +46,12 @@
|
|||||||
<string name="login_invalid_pin">Nieprawidłowy PIN</string>
|
<string name="login_invalid_pin">Nieprawidłowy PIN</string>
|
||||||
<string name="login_invalid_token">Nieprawidłowy token</string>
|
<string name="login_invalid_token">Nieprawidłowy token</string>
|
||||||
<string name="login_expired_token">Token stracił ważność</string>
|
<string name="login_expired_token">Token stracił ważność</string>
|
||||||
|
<string name="login_invalid_email">Niepoprawny adres email</string>
|
||||||
<string name="login_invalid_symbol">Niepoprawny symbol</string>
|
<string name="login_invalid_symbol">Niepoprawny symbol</string>
|
||||||
<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 Uczeń -> Dostęp Mobilny -> Zarejestruj urządzenie mobilne</string>
|
<string name="login_symbol_helper">Symbol znajdziesz na stronie dziennika w Uczeń -> Dostęp Mobilny -> Zarejestruj urządzenie mobilne</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_privacy_policy">Polityka prywatności</string>
|
<string name="login_privacy_policy">Polityka prywatności</string>
|
||||||
@ -56,6 +59,9 @@
|
|||||||
<string name="login_contact_email">Email</string>
|
<string name="login_contact_email">Email</string>
|
||||||
<string name="login_contact_discord">Discord</string>
|
<string name="login_contact_discord">Discord</string>
|
||||||
<string name="login_email_intent_title">Wyślij email</string>
|
<string name="login_email_intent_title">Wyślij email</string>
|
||||||
|
<string name="login_recover_button">Nie pamiętam hasła</string>
|
||||||
|
<string name="login_recover_title">Przywróć swoje konto</string>
|
||||||
|
<string name="login_recover">Przywróć</string>
|
||||||
<string name="login_signed_in">Uczeń jest już zalogowany</string>
|
<string name="login_signed_in">Uczeń jest już zalogowany</string>
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
<string name="login_header_symbol">Впишите \"symbol\"</string>
|
<string name="login_header_symbol">Впишите \"symbol\"</string>
|
||||||
<string name="login_nickname_hint">Имя пользователя</string>
|
<string name="login_nickname_hint">Имя пользователя</string>
|
||||||
<string name="login_email_hint">Электронная почта</string>
|
<string name="login_email_hint">Электронная почта</string>
|
||||||
|
<string name="login_login_pesel_email_hint">Логин, PESEL или электронная почта</string>
|
||||||
<string name="login_password_hint">Пароль</string>
|
<string name="login_password_hint">Пароль</string>
|
||||||
<string name="login_host_hint">Дневник</string>
|
<string name="login_host_hint">Дневник</string>
|
||||||
<string name="login_type_api">Мобильный API</string>
|
<string name="login_type_api">Мобильный API</string>
|
||||||
@ -39,12 +40,14 @@
|
|||||||
<string name="login_pin_hint">PIN</string>
|
<string name="login_pin_hint">PIN</string>
|
||||||
<string name="login_api_key_hint">клавиша API</string>
|
<string name="login_api_key_hint">клавиша API</string>
|
||||||
<string name="login_symbol_hint">Symbol</string>
|
<string name="login_symbol_hint">Symbol</string>
|
||||||
|
<string name="login_symbol_hint_optional">Символ (необязательно)</string>
|
||||||
<string name="login_sign_in">Войти</string>
|
<string name="login_sign_in">Войти</string>
|
||||||
<string name="login_invalid_password">Слишком короткий пароль</string>
|
<string name="login_invalid_password">Слишком короткий пароль</string>
|
||||||
<string name="login_incorrect_password">Указаны неверные данные</string>
|
<string name="login_incorrect_password">Указаны неверные данные</string>
|
||||||
<string name="login_invalid_pin">Недействительный PIN</string>
|
<string name="login_invalid_pin">Недействительный PIN</string>
|
||||||
<string name="login_invalid_token">Недействительный token</string>
|
<string name="login_invalid_token">Недействительный token</string>
|
||||||
<string name="login_expired_token">Токен просрочен</string>
|
<string name="login_expired_token">Токен просрочен</string>
|
||||||
|
<string name="login_invalid_email">Неверный адрес электронной почты</string>
|
||||||
<string name="login_invalid_symbol">Недействительный symbol</string>
|
<string name="login_invalid_symbol">Недействительный symbol</string>
|
||||||
<string name="login_incorrect_symbol">Не удалось найти ученика. Пожалуйста, проверьте \"symbol\"</string>
|
<string name="login_incorrect_symbol">Не удалось найти ученика. Пожалуйста, проверьте \"symbol\"</string>
|
||||||
<string name="login_field_required">Это поле обязательно</string>
|
<string name="login_field_required">Это поле обязательно</string>
|
||||||
@ -57,6 +60,9 @@
|
|||||||
<string name="login_contact_email">Электронная почта</string>
|
<string name="login_contact_email">Электронная почта</string>
|
||||||
<string name="login_contact_discord">Discord</string>
|
<string name="login_contact_discord">Discord</string>
|
||||||
<string name="login_email_intent_title">Отправить письмо</string>
|
<string name="login_email_intent_title">Отправить письмо</string>
|
||||||
|
<string name="login_recover">восстановление</string>
|
||||||
|
<string name="login_recover_button">Я не помню пароль</string>
|
||||||
|
<string name="login_recover_title">Восстановите свой аккаунт</string>
|
||||||
<string name="login_signed_in">Студент уже вошел в систему</string>
|
<string name="login_signed_in">Студент уже вошел в систему</string>
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
<string name="login_header_symbol">Enter the symbol</string>
|
<string name="login_header_symbol">Enter the symbol</string>
|
||||||
<string name="login_nickname_hint">Username</string>
|
<string name="login_nickname_hint">Username</string>
|
||||||
<string name="login_email_hint">Email</string>
|
<string name="login_email_hint">Email</string>
|
||||||
|
<string name="login_login_pesel_email_hint">Login, PESEL or e-mail</string>
|
||||||
<string name="login_password_hint">Password</string>
|
<string name="login_password_hint">Password</string>
|
||||||
<string name="login_host_hint">Register</string>
|
<string name="login_host_hint">Register</string>
|
||||||
<string name="login_type_api">Mobile API</string>
|
<string name="login_type_api">Mobile API</string>
|
||||||
@ -39,12 +40,14 @@
|
|||||||
<string name="login_pin_hint">PIN</string>
|
<string name="login_pin_hint">PIN</string>
|
||||||
<string name="login_api_key_hint">API key</string>
|
<string name="login_api_key_hint">API key</string>
|
||||||
<string name="login_symbol_hint">Symbol</string>
|
<string name="login_symbol_hint">Symbol</string>
|
||||||
|
<string name="login_symbol_hint_optional">Symbol (optional)</string>
|
||||||
<string name="login_sign_in">Sign in</string>
|
<string name="login_sign_in">Sign in</string>
|
||||||
<string name="login_invalid_password">Password too short</string>
|
<string name="login_invalid_password">Password too short</string>
|
||||||
<string name="login_incorrect_password">Login details are incorrect</string>
|
<string name="login_incorrect_password">Login details are incorrect</string>
|
||||||
<string name="login_invalid_pin">Invalid PIN</string>
|
<string name="login_invalid_pin">Invalid PIN</string>
|
||||||
<string name="login_invalid_token">Invalid token</string>
|
<string name="login_invalid_token">Invalid token</string>
|
||||||
<string name="login_expired_token">Token expired</string>
|
<string name="login_expired_token">Token expired</string>
|
||||||
|
<string name="login_invalid_email">Invalid email</string>
|
||||||
<string name="login_invalid_symbol">Invalid symbol</string>
|
<string name="login_invalid_symbol">Invalid symbol</string>
|
||||||
<string name="login_incorrect_symbol">Student not found. Check the symbol</string>
|
<string name="login_incorrect_symbol">Student not found. Check the symbol</string>
|
||||||
<string name="login_field_required">This field is required</string>
|
<string name="login_field_required">This field is required</string>
|
||||||
@ -59,6 +62,9 @@
|
|||||||
<string name="login_email_intent_title">Send email</string>
|
<string name="login_email_intent_title">Send email</string>
|
||||||
<string name="login_email_subject" translatable="false">Zgłoszenie: Problemy z logowaniem</string>
|
<string name="login_email_subject" translatable="false">Zgłoszenie: Problemy z logowaniem</string>
|
||||||
<string name="login_email_text" translatable="false">Informacje o aplikacji:\n\nUrządzenie: %1$s\nWersja SDK: %2$s\nWersja aplikacji: %3$s\n\nOpis problemu:</string>
|
<string name="login_email_text" translatable="false">Informacje o aplikacji:\n\nUrządzenie: %1$s\nWersja SDK: %2$s\nWersja aplikacji: %3$s\n\nOpis problemu:</string>
|
||||||
|
<string name="login_recover_button">I forgot my password</string>
|
||||||
|
<string name="login_recover_title">Recover your account</string>
|
||||||
|
<string name="login_recover">Recover</string>
|
||||||
<string name="login_signed_in">Student is already signed in</string>
|
<string name="login_signed_in">Student is already signed in</string>
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user