Add more details in email template (#751)

This commit is contained in:
Mikołaj Pich 2020-04-04 20:57:50 +02:00 committed by GitHub
parent 18c1153e12
commit bf61dd1bad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 101 additions and 71 deletions

View File

@ -128,7 +128,7 @@ configurations.all {
}
dependencies {
implementation "io.github.wulkanowy:sdk:bff34b1"
implementation "io.github.wulkanowy:sdk:0cf724a"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.core:core-ktx:1.2.0"

View File

@ -1,12 +1,6 @@
package io.github.wulkanowy.ui.modules.about
import android.content.Intent
import android.content.Intent.ACTION_SENDTO
import android.content.Intent.EXTRA_EMAIL
import android.content.Intent.EXTRA_SUBJECT
import android.content.Intent.EXTRA_TEXT
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -23,6 +17,7 @@ import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.getCompatDrawable
import io.github.wulkanowy.utils.openEmailClient
import io.github.wulkanowy.utils.openInternetBrowser
import io.github.wulkanowy.utils.setOnItemClickListener
import kotlinx.android.synthetic.main.fragment_about.*
@ -124,26 +119,17 @@ class AboutFragment : BaseFragment(), AboutView, MainView.TitledView {
}
override fun openEmailClient() {
val intent = Intent(ACTION_SENDTO)
.apply {
data = Uri.parse("mailto:")
putExtra(EXTRA_EMAIL, arrayOf("wulkanowyinc@gmail.com"))
putExtra(EXTRA_SUBJECT, "Zgłoszenie błędu")
putExtra(EXTRA_TEXT, "Tu umieść treść zgłoszenia\n\n${"-".repeat(40)}\n " +
"""
Build: ${appInfo.versionCode}
SDK: ${appInfo.systemVersion}
Device: ${appInfo.systemManufacturer} ${appInfo.systemModel}
""".trimIndent())
requireContext().openEmailClient(
chooserTitle = getString(R.string.about_feedback),
email = "wulkanowyinc@gmail.com",
subject = "Zgłoszenie błędu",
body = requireContext().getString(R.string.about_feedback_template,
"${appInfo.systemManufacturer} ${appInfo.systemModel}", appInfo.systemVersion.toString(), appInfo.versionName
),
onActivityNotFound = {
requireContext().openInternetBrowser("https://github.com/wulkanowy/wulkanowy/issues", ::showMessage)
}
context?.let {
if (intent.resolveActivity(it.packageManager) != null) {
startActivity(Intent.createChooser(intent, getString(R.string.about_feedback)))
} else {
it.openInternetBrowser("https://github.com/wulkanowy/wulkanowy/issues", ::showMessage)
}
}
)
}
override fun openFaqPage() {

View File

@ -233,12 +233,18 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
}
}
override fun openEmail() {
override fun openEmail(lastError: String) {
context?.openEmailClient(
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)
chooserTitle = requireContext().getString(R.string.login_email_intent_title),
email = "wulkanowyinc@gmail.com",
subject = requireContext().getString(R.string.login_email_subject),
body = requireContext().getString(R.string.login_email_text,
"${appInfo.systemManufacturer} ${appInfo.systemModel}",
appInfo.systemVersion.toString(),
appInfo.versionName,
"$formHostValue/$formSymbolValue",
lastError
)
)
}
}

View File

@ -16,6 +16,8 @@ class LoginFormPresenter @Inject constructor(
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<LoginFormView>(loginErrorHandler, studentRepository, schedulers) {
private var lastError: Throwable? = null
override fun onAttachView(view: LoginFormView) {
super.onAttachView(view)
view.run {
@ -109,6 +111,7 @@ class LoginFormPresenter @Inject constructor(
Timber.i("Login result: An exception occurred")
analytics.logEvent("registration_form", "success" to false, "students" to -1, "scrapperBaseUrl" to host, "error" to it.message.ifNullOrBlank { "No message" })
loginErrorHandler.dispatch(it)
lastError = it
view?.showContact(true)
}))
}
@ -118,7 +121,7 @@ class LoginFormPresenter @Inject constructor(
}
fun onEmailClick() {
view?.openEmail()
view?.openEmail(lastError?.message.ifNullOrBlank { "none" })
}
fun onRecoverClick() {

View File

@ -67,7 +67,7 @@ interface LoginFormView : BaseView {
fun openFaqPage()
fun openEmail()
fun openEmail(lastError: String)
fun openAdvancedLogin()

View File

@ -101,12 +101,17 @@ class LoginStudentSelectFragment : BaseFragment(), LoginStudentSelectView {
context?.openInternetBrowser("https://discord.gg/vccAQBr", ::showMessage)
}
override fun openEmail() {
override fun openEmail(lastError: String) {
context?.openEmailClient(
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)
chooserTitle = requireContext().getString(R.string.login_email_intent_title),
email = "wulkanowyinc@gmail.com",
subject = requireContext().getString(R.string.login_email_subject),
body = requireContext().getString(R.string.login_email_text, appInfo.systemModel,
appInfo.systemVersion.toString(),
appInfo.versionName,
"Select users to log in",
lastError
)
)
}
}

View File

@ -8,7 +8,6 @@ import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.ifNullOrBlank
import io.reactivex.Single
import timber.log.Timber
import java.io.Serializable
import javax.inject.Inject
@ -20,6 +19,8 @@ class LoginStudentSelectPresenter @Inject constructor(
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<LoginStudentSelectView>(loginErrorHandler, studentRepository, schedulers) {
private var lastError: Throwable? = null
var students = emptyList<Student>()
private var selectedStudents = mutableListOf<Student>()
@ -83,6 +84,7 @@ class LoginStudentSelectPresenter @Inject constructor(
})
}, {
errorHandler.dispatch(it)
lastError = it
view?.updateData(students.map { student -> LoginStudentSelectItem(student, false) })
})
)
@ -109,6 +111,7 @@ class LoginStudentSelectPresenter @Inject constructor(
students.forEach { analytics.logEvent("registration_student_select", "success" to false, "scrapperBaseUrl" to it.scrapperBaseUrl, "symbol" to it.symbol, "error" to error.message.ifNullOrBlank { "No message" }) }
Timber.i("Registration result: An exception occurred ")
loginErrorHandler.dispatch(error)
lastError = error
view?.apply {
showProgress(false)
showContent(true)
@ -122,6 +125,6 @@ class LoginStudentSelectPresenter @Inject constructor(
}
fun onEmailClick() {
view?.openEmail()
view?.openEmail(lastError?.message.ifNullOrBlank { "empty" })
}
}

View File

@ -20,5 +20,5 @@ interface LoginStudentSelectView : BaseView {
fun openDiscordInvite()
fun openEmail()
fun openEmail(lastError: String)
}

View File

@ -130,12 +130,18 @@ class LoginSymbolFragment : BaseFragment(), LoginSymbolView {
context?.openInternetBrowser("https://wulkanowy.github.io/czesto-zadawane-pytania/co-to-jest-symbol", ::showMessage)
}
override fun openEmail() {
override fun openEmail(host: String, lastError: String) {
context?.openEmailClient(
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)
chooserTitle = requireContext().getString(R.string.login_email_intent_title),
email = "wulkanowyinc@gmail.com",
subject = requireContext().getString(R.string.login_email_subject),
body = requireContext().getString(R.string.login_email_text,
"${appInfo.systemManufacturer} ${appInfo.systemModel}",
appInfo.systemVersion.toString(),
appInfo.versionName,
"$host/${loginSymbolName.text}",
lastError
)
)
}
}

View File

@ -18,6 +18,8 @@ class LoginSymbolPresenter @Inject constructor(
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<LoginSymbolView>(loginErrorHandler, studentRepository, schedulers) {
private var lastError: Throwable? = null
var loginData: Triple<String, String, String>? = null
@Suppress("UNCHECKED_CAST")
@ -37,13 +39,15 @@ class LoginSymbolPresenter @Inject constructor(
}
fun attemptLogin(symbol: String) {
if (loginData == null) throw IllegalArgumentException("Login data is null")
if (symbol.isBlank()) {
view?.setErrorSymbolRequire()
return
}
disposable.add(
Single.fromCallable { if (loginData == null) throw IllegalArgumentException("Login data is null") else loginData }
Single.fromCallable { loginData }
.flatMap { studentRepository.getStudentsScrapper(it.first, it.second, it.third, symbol) }
.subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread)
@ -77,6 +81,7 @@ class LoginSymbolPresenter @Inject constructor(
Timber.i("Login with symbol result: An exception occurred")
analytics.logEvent("registration_symbol", "success" to false, "students" to -1, "scrapperBaseUrl" to loginData?.third, "symbol" to symbol, "error" to it.message.ifNullOrBlank { "No message" })
loginErrorHandler.dispatch(it)
lastError = it
view?.showContact(true)
}))
}
@ -94,6 +99,6 @@ class LoginSymbolPresenter @Inject constructor(
}
fun onEmailClick() {
view?.openEmail()
view?.openEmail(loginData?.third.orEmpty(), lastError?.message.ifNullOrBlank { "empty" })
}
}

View File

@ -31,5 +31,5 @@ interface LoginSymbolView : BaseView {
fun openFaqPage()
fun openEmail()
fun openEmail(host: String, lastError: String)
}

View File

@ -32,12 +32,16 @@ fun Context.openInternetBrowser(uri: String, onActivityNotFound: (uri: String) -
}
}
fun Context.openEmailClient(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.openEmailClient(chooserTitle: String, email: String, subject: String, body: String, onActivityNotFound: () -> Unit = {}) {
val intent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:")).apply {
putExtra(Intent.EXTRA_EMAIL, arrayOf(email))
putExtra(Intent.EXTRA_SUBJECT, subject)
putExtra(Intent.EXTRA_TEXT, body)
}
if (intent.resolveActivity(packageManager) != null) {
startActivity(Intent.createChooser(intent, chooserTitle))
} else onActivityNotFound()
}
fun Context.openNavigation(location: String) {

View File

@ -108,31 +108,41 @@
android:text="@string/login_header_symbol"
android:textSize="16sp"
app:fontFamily="sans-serif-light"
app:layout_constraintBottom_toTopOf="@+id/loginSymbolNameLayout"
app:layout_constraintBottom_toTopOf="@+id/loginSymbolHelper"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/loginSymbolContact"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/loginSymbolHelper"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="32dp"
android:gravity="center_horizontal"
android:text="@string/login_symbol_helper"
app:fontFamily="sans-serif-light"
app:layout_constraintBottom_toTopOf="@id/loginSymbolNameLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/loginSymbolHeader"
app:layout_constraintVertical_chainStyle="packed" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/loginSymbolNameLayout"
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="48dp"
android:layout_marginEnd="24dp"
android:layout_marginRight="24dp"
android:layout_margin="24dp"
android:hint="@string/login_symbol_hint"
app:helperText="@string/login_symbol_helper"
app:helperTextEnabled="true"
app:layout_constraintBottom_toTopOf="@+id/loginSymbolSignIn"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/loginSymbolHeader">
app:layout_constraintTop_toBottomOf="@+id/loginSymbolHelper">
<AutoCompleteTextView
android:id="@+id/loginSymbolName"

View File

@ -53,7 +53,7 @@
<string name="login_incorrect_symbol">Student nicht gefunden. Überprüfen Sie das Symbol</string>
<string name="login_field_required">Dieses Datenfeld ist erforderlich</string>
<string name="login_duplicate_student">Ausgewählter Student ist bereits angemeldet.</string>
<string name="login_symbol_helper">Das Symbol finden Sie auf der Registerseite unter Uczeń -> Dostęp Mobilny -> Zarejestruj urządzenie mobilne</string>
<string name="login_symbol_helper">Das Symbol finden Sie auf der Registerseite unter <b>Uczeń</b> →&#160;<b>Dostęp Mobilny</b>&#160;<b>Zarejestruj urządzenie mobilne</b></string>
<string name="login_select_student">Wählen Sie die Studenten aus, die sich bei der Anwendung anmelden sollen.</string>
<string name="login_advanced">Andere Optionen</string>
<string name="login_privacy_policy">Datenschutzerklärung</string>

View File

@ -44,7 +44,7 @@
<string name="login_api_key_hint">Klucz API</string>
<string name="login_sign_in">Zaloguj</string>
<string name="login_invalid_password">To hasło jest za krótkie</string>
<string name="login_incorrect_password">Dane logowania są niepoprawne. Upewnij się, że został wybrany odpowiedni dziennik UONET+</string>
<string name="login_incorrect_password">Dane logowania są niepoprawne. Upewnij się, że został wybrany odpowiedni dziennik UONET+ w polu poniżej</string>
<string name="login_invalid_pin">Nieprawidłowy PIN</string>
<string name="login_invalid_token">Nieprawidłowy token</string>
<string name="login_expired_token">Token stracił ważność</string>
@ -54,7 +54,7 @@
<string name="login_incorrect_symbol">Nie znaleziono ucznia. Sprawdź symbol</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_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&#160;<b>Uczeń</b> →&#160;<b>Dostęp Mobilny</b>&#160;<b>Zarejestruj urządzenie mobilne</b></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_warning_mobile_api">W tym trybie nie działa szczęśliwy numerek, uczeń na tle klasy, podsumowanie frekwencji, usprawiedliwianie nieobecności, lekcje zrealizowane, informacje o szkole i podgląd listy zarejestrowanych urządzeń</string>

View File

@ -54,7 +54,7 @@
<string name="login_incorrect_symbol">Не удалось найти ученика. Пожалуйста, проверьте \"symbol\"</string>
<string name="login_field_required">Это поле обязательно</string>
<string name="login_duplicate_student">Данный ученик уже авторизован</string>
<string name="login_symbol_helper">Вы можете найти \"symbol\" в Uczeń -&gt; Dostęp Mobilny -&gt; Zarejestruj urządzenie mobilne</string>
<string name="login_symbol_helper">Вы можете найти \"symbol\" в <b>Uczeń</b> →&#160;<b>Dostęp Mobilny</b>&#160;<b>Zarejestruj urządzenie mobilne</b></string>
<string name="login_select_student">Выберите учеников для авторизации в приложении</string>
<string name="login_advanced">Другие варианты</string>
<string name="login_privacy_policy">Политика приватности</string>

View File

@ -55,7 +55,7 @@
<string name="login_incorrect_symbol">Не вдалося знайти учня. Будь ласка, перевірте \"symbol\"</string>
<string name="login_field_required">Це поле обов\'язкове</string>
<string name="login_duplicate_student">Даний учень вже авторизований</string>
<string name="login_symbol_helper">Ви можете знайти \"symbol\" в Uczeń -&gt; Dostęp Mobilny -&gt; Zarejestruj urządzenie mobilne</string>
<string name="login_symbol_helper">Ви можете знайти \"symbol\" в <b>Uczeń</b> →&#160;<b>Dostęp Mobilny</b>&#160;<b>Zarejestruj urządzenie mobilne</b></string>
<string name="login_select_student">Виберіть учнів для авторизації в додатку</string>
<string name="login_advanced">Інші варіанти</string>
<string name="login_privacy_policy">Політика приватності</string>

View File

@ -55,7 +55,7 @@
<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_duplicate_student">Selected student is already logged in</string>
<string name="login_symbol_helper">The symbol can be found on the register page in Uczeń -> Dostęp Mobilny -> Zarejestruj urządzenie mobilne</string>
<string name="login_symbol_helper">The symbol can be found on the register page in <b>Uczeń</b> →&#160;<b>Dostęp Mobilny</b>&#160;<b>Zarejestruj urządzenie mobilne</b></string>
<string name="login_select_student">Select students to log in to the application</string>
<string name="login_advanced">Other options</string>
<string name="login_advanced_warning_mobile_api">In this mode, a lucky number does not work, a class grade stats, summary of attendance, excuse for absence, completed lessons, school information and preview of the list of registered devices</string>
@ -66,8 +66,9 @@
<string name="login_contact_email">Email</string>
<string name="login_contact_discord">Discord</string>
<string name="login_email_intent_title">Send email</string>
<string name="login_email_details">Describe details of problem:</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\nDodatkowe informacje: %4$s\nOstatni błąd: %5$s\n\nOpis problemu: </string>
<string name="login_recover_warning">Make sure the correct UONET+ register is selected!</string>
<string name="login_recover_button">I forgot my password</string>
<string name="login_recover_title">Recover your account</string>
@ -295,6 +296,7 @@
<string name="about_homepage_summary">Visit the website and help develop the application</string>
<string name="about_licenses">Licenses</string>
<string name="about_licenses_summary">Licenses of libraries used in the application</string>
<string name="about_feedback_template" translatable="false">Informacje o aplikacji:\n\nUrządzenie: %1$s\nWersja SDK: %2$s\nWersja aplikacji: %3$s\n\nTreść zgłoszenia:</string>
<!--Licenses-->