Contact info after failed login (#556)

This commit is contained in:
Dominik Korsa
2019-10-20 19:10:32 +02:00
committed by Rafał Borcz
parent ce9b12eb93
commit 7e30524876
15 changed files with 351 additions and 6 deletions

View File

@ -21,6 +21,7 @@ import io.github.wulkanowy.utils.openInternetBrowser
import io.github.wulkanowy.utils.showSoftInput
import kotlinx.android.synthetic.main.fragment_login_form.*
import javax.inject.Inject
import io.github.wulkanowy.utils.openEmail
class LoginFormFragment : BaseFragment(), LoginFormView {
@ -62,6 +63,8 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
loginFormHost.setOnItemClickListener { _, _, _, _ -> presenter.onHostSelected() }
loginFormSignIn.setOnClickListener { presenter.onSignInClick() }
loginFormPrivacyLink.setOnClickListener { presenter.onPrivacyLinkClick() }
loginFormContactDiscord.setOnClickListener { presenter.onDiscordClick() }
loginFormContactEmail.setOnClickListener { presenter.onEmailClick() }
loginFormPass.setOnEditorActionListener { _, id, _ ->
if (id == IME_ACTION_DONE || id == IME_NULL) loginFormSignIn.callOnClick() else false
@ -154,8 +157,25 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
context?.openInternetBrowser("https://wulkanowy.github.io/polityka-prywatnosci.html", ::showMessage)
}
override fun showContact(show: Boolean) {
loginFormContact.visibility = if (show) VISIBLE else GONE
}
override fun onDestroyView() {
super.onDestroyView()
presenter.onDetachView()
}
override fun openDiscordInvite() {
context?.openInternetBrowser("https://discord.gg/vccAQBr", ::showMessage)
}
override fun openEmail() {
context?.openEmail(
requireContext().getString(R.string.login_email_intent_title),
"wulkanowyinc@gmail.com",
requireContext().getString(R.string.login_email_subject),
requireContext().getString(R.string.login_email_text, appInfo.systemModel, appInfo.systemVersion.toString(), appInfo.versionName)
)
}
}

View File

@ -22,6 +22,7 @@ class LoginFormPresenter @Inject constructor(
super.onAttachView(view)
view.run {
initView()
showContact(false)
if (appInfo.isDebug) showVersion() else showPrivacyPolicy()
loginErrorHandler.onBadCredentials = {
@ -86,9 +87,18 @@ class LoginFormPresenter @Inject constructor(
Timber.i("Login result: An exception occurred")
analytics.logEvent("registration_form", "success" to false, "students" to -1, "endpoint" to endpoint, "error" to it.message.ifNullOrBlank { "No message" })
loginErrorHandler.dispatch(it)
view?.showContact(true)
}))
}
fun onDiscordClick() {
view?.openDiscordInvite()
}
fun onEmailClick() {
view?.openEmail()
}
private fun validateCredentials(login: String, password: String): Boolean {
var isCorrect = true

View File

@ -42,4 +42,10 @@ interface LoginFormView : BaseView {
fun notifyParentAccountLogged(students: List<Student>, loginData: Triple<String, String, String>)
fun openPrivacyPolicyPage()
fun showContact(show: Boolean)
fun openDiscordInvite()
fun openEmail()
}

View File

@ -13,6 +13,9 @@ import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.openEmail
import io.github.wulkanowy.utils.openInternetBrowser
import io.github.wulkanowy.utils.setOnItemClickListener
import kotlinx.android.synthetic.main.fragment_login_student_select.*
import java.io.Serializable
@ -26,6 +29,9 @@ class LoginStudentSelectFragment : BaseFragment(), LoginStudentSelectView {
@Inject
lateinit var loginAdapter: FlexibleAdapter<AbstractFlexibleItem<*>>
@Inject
lateinit var appInfo: AppInfo
companion object {
const val SAVED_STUDENTS = "STUDENTS"
@ -44,6 +50,8 @@ class LoginStudentSelectFragment : BaseFragment(), LoginStudentSelectView {
override fun initView() {
loginStudentSelectSignIn.setOnClickListener { presenter.onSignIn() }
loginAdapter.apply { setOnItemClickListener { presenter.onItemSelected(it) } }
loginStudentSelectContactDiscord.setOnClickListener { presenter.onDiscordClick() }
loginStudentSelectContactEmail.setOnClickListener { presenter.onEmailClick() }
loginStudentSelectRecycler.apply {
adapter = loginAdapter
@ -80,8 +88,25 @@ class LoginStudentSelectFragment : BaseFragment(), LoginStudentSelectView {
outState.putSerializable(SAVED_STUDENTS, presenter.students as Serializable)
}
override fun showContact(show: Boolean) {
loginStudentSelectContact.visibility = if (show) VISIBLE else GONE
}
override fun onDestroyView() {
presenter.onDetachView()
super.onDestroyView()
}
override fun openDiscordInvite() {
context?.openInternetBrowser("https://discord.gg/vccAQBr", ::showMessage)
}
override fun openEmail() {
context?.openEmail(
requireContext().getString(R.string.login_email_intent_title),
"wulkanowyinc@gmail.com",
requireContext().getString(R.string.login_email_subject),
requireContext().getString(R.string.login_email_text, appInfo.systemModel, appInfo.systemVersion.toString(), appInfo.versionName)
)
}
}

View File

@ -27,6 +27,7 @@ class LoginStudentSelectPresenter @Inject constructor(
super.onAttachView(view)
view.run {
initView()
showContact(false)
enableSignIn(false)
loginErrorHandler.onStudentDuplicate = {
showMessage(it)
@ -88,7 +89,16 @@ class LoginStudentSelectPresenter @Inject constructor(
view?.apply {
showProgress(false)
showContent(true)
showContact(true)
}
}))
}
fun onDiscordClick() {
view?.openDiscordInvite()
}
fun onEmailClick() {
view?.openEmail()
}
}

View File

@ -15,4 +15,10 @@ interface LoginStudentSelectView : BaseView {
fun showContent(show: Boolean)
fun enableSignIn(enable: Boolean)
fun showContact(show: Boolean)
fun openDiscordInvite()
fun openEmail()
}

View File

@ -14,7 +14,10 @@ import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.hideSoftInput
import io.github.wulkanowy.utils.openEmail
import io.github.wulkanowy.utils.openInternetBrowser
import io.github.wulkanowy.utils.showSoftInput
import kotlinx.android.synthetic.main.fragment_login_symbol.*
import javax.inject.Inject
@ -24,6 +27,9 @@ class LoginSymbolFragment : BaseFragment(), LoginSymbolView {
@Inject
lateinit var presenter: LoginSymbolPresenter
@Inject
lateinit var appInfo: AppInfo
companion object {
private const val SAVED_LOGIN_DATA = "LOGIN_DATA"
@ -44,6 +50,8 @@ class LoginSymbolFragment : BaseFragment(), LoginSymbolView {
override fun initView() {
loginSymbolSignIn.setOnClickListener { presenter.attemptLogin(loginSymbolName.text.toString()) }
loginSymbolContactDiscord.setOnClickListener { presenter.onDiscordClick() }
loginSymbolContactEmail.setOnClickListener { presenter.onEmailClick() }
loginSymbolName.doOnTextChanged { _, _, _, _ -> presenter.onSymbolTextChanged() }
@ -109,8 +117,25 @@ class LoginSymbolFragment : BaseFragment(), LoginSymbolView {
outState.putSerializable(SAVED_LOGIN_DATA, presenter.loginData)
}
override fun showContact(show: Boolean) {
loginSymbolContact.visibility = if (show) VISIBLE else GONE
}
override fun onDestroyView() {
super.onDestroyView()
presenter.onDetachView()
}
override fun openDiscordInvite() {
context?.openInternetBrowser("https://discord.gg/vccAQBr", ::showMessage)
}
override fun openEmail() {
context?.openEmail(
requireContext().getString(R.string.login_email_intent_title),
"wulkanowyinc@gmail.com",
requireContext().getString(R.string.login_email_subject),
requireContext().getString(R.string.login_email_text, appInfo.systemModel, appInfo.systemVersion.toString(), appInfo.versionName)
)
}
}

View File

@ -23,7 +23,10 @@ class LoginSymbolPresenter @Inject constructor(
@Suppress("UNCHECKED_CAST")
fun onAttachView(view: LoginSymbolView, savedLoginData: Serializable?) {
super.onAttachView(view)
view.initView()
view.run {
initView()
showContact(false)
}
if (savedLoginData is Triple<*, *, *>) {
loginData = savedLoginData as Triple<String, String, String>
}
@ -64,6 +67,7 @@ class LoginSymbolPresenter @Inject constructor(
if (it.isEmpty()) {
Timber.i("Login with symbol result: Empty student list")
setErrorSymbolIncorrect()
view?.showContact(true)
} else {
Timber.i("Login with symbol result: Success")
notifyParentAccountLogged(it)
@ -73,6 +77,7 @@ class LoginSymbolPresenter @Inject constructor(
Timber.i("Login with symbol result: An exception occurred")
analytics.logEvent("registration_symbol", "success" to false, "students" to -1, "endpoint" to loginData?.third, "symbol" to symbol, "error" to it.message.ifNullOrBlank { "No message" })
loginErrorHandler.dispatch(it)
view?.showContact(true)
}))
}
@ -83,4 +88,12 @@ class LoginSymbolPresenter @Inject constructor(
showSoftKeyboard()
}
}
fun onDiscordClick() {
view?.openDiscordInvite()
}
fun onEmailClick() {
view?.openEmail()
}
}

View File

@ -26,4 +26,10 @@ interface LoginSymbolView : BaseView {
fun showContent(show: Boolean)
fun notifyParentAccountLogged(students: List<Student>)
fun showContact(show: Boolean)
fun openDiscordInvite()
fun openEmail()
}

View File

@ -2,12 +2,14 @@ package io.github.wulkanowy.utils
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.util.DisplayMetrics.DENSITY_DEFAULT
import androidx.annotation.AttrRes
import androidx.annotation.ColorInt
import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import io.github.wulkanowy.R
@ColorInt
fun Context.getThemeAttrColor(@AttrRes colorAttr: Int): Int {
@ -31,4 +33,12 @@ fun Context.openInternetBrowser(uri: String, onActivityNotFound: (uri: String) -
}
}
fun Context.openEmail(chooserTitle: String, email: String, subject: String?, body: String?) {
val emailIntent = Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", email, null))
emailIntent.putExtra(Intent.EXTRA_EMAIL, arrayOf(email))
if (subject != null) emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject)
if (body != null) emailIntent.putExtra(Intent.EXTRA_TEXT, body)
startActivity(Intent.createChooser(emailIntent, chooserTitle))
}
fun Context.dpToPx(dp: Float) = dp * resources.displayMetrics.densityDpi / DENSITY_DEFAULT