diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt index 4849b213..8ea4222c 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt @@ -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) + ) + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt index d5b81b5b..bdab1dad 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt @@ -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 diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt index 097b6f62..7eec9477 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt @@ -42,4 +42,10 @@ interface LoginFormView : BaseView { fun notifyParentAccountLogged(students: List, loginData: Triple) fun openPrivacyPolicyPage() + + fun showContact(show: Boolean) + + fun openDiscordInvite() + + fun openEmail() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt index 5c48cf2f..dba0c951 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt @@ -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> + @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) + ) + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt index e02227cb..288531dc 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt @@ -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() + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt index 3967313c..23877100 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt @@ -15,4 +15,10 @@ interface LoginStudentSelectView : BaseView { fun showContent(show: Boolean) fun enableSignIn(enable: Boolean) + + fun showContact(show: Boolean) + + fun openDiscordInvite() + + fun openEmail() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt index f4f0eb9e..724e3fbb 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt @@ -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) + ) + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolPresenter.kt index 5a7a3777..8e4dd3b0 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolPresenter.kt @@ -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 } @@ -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() + } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolView.kt index 2e5143ef..9b5340cf 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolView.kt @@ -26,4 +26,10 @@ interface LoginSymbolView : BaseView { fun showContent(show: Boolean) fun notifyParentAccountLogged(students: List) + + fun showContact(show: Boolean) + + fun openDiscordInvite() + + fun openEmail() } diff --git a/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt index a941c6fa..84200b3a 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt @@ -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 diff --git a/app/src/main/res/layout/fragment_login_form.xml b/app/src/main/res/layout/fragment_login_form.xml index 7627e71b..545b7726 100644 --- a/app/src/main/res/layout/fragment_login_form.xml +++ b/app/src/main/res/layout/fragment_login_form.xml @@ -25,15 +25,79 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_login_student_select.xml b/app/src/main/res/layout/fragment_login_student_select.xml index d123b553..64e06cbd 100644 --- a/app/src/main/res/layout/fragment_login_student_select.xml +++ b/app/src/main/res/layout/fragment_login_student_select.xml @@ -19,6 +19,76 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Symbol znajdziesz na stronie dziennika w Uczeń -> Dostęp Mobilny -> Zarejestruj urządzenie mobilne Wybierz uczniów do zalogowania w aplikacji Polityka prywatności + Problemy z logowaniem? Napisz do nas! + Email + Discord + Wyślij email diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 27e43dc5..c4b5218d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -36,6 +36,12 @@ The symbol can be found on the register page in Uczeń -> Dostęp Mobilny -> Zarejestruj urządzenie mobilne Select students to log in to the application Privacy policy + Trouble signing in? Contact us! + Email + Discord + Send email + Zgłoszenie: Problemy z logowaniem + Informacje o aplikacji:\n\nUrządzenie: %1$s\nWersja SDK: %2$s\nWersja aplikacji: %3$s\n\nOpis problemu: