forked from github/wulkanowy-mirror
Split login form for two fragments (#230)
This commit is contained in:
parent
2f87779647
commit
1b1f2ae3bb
1
.idea/codeStyles/Project.xml
generated
1
.idea/codeStyles/Project.xml
generated
@ -19,7 +19,6 @@
|
||||
<option name="CONTINUATION_INDENT_IN_SUPERTYPE_LISTS" value="false" />
|
||||
<option name="CONTINUATION_INDENT_IN_IF_CONDITIONS" value="false" />
|
||||
<option name="CONTINUATION_INDENT_IN_ELVIS" value="false" />
|
||||
<option name="WRAP_EXPRESSION_BODY_FUNCTIONS" value="1" />
|
||||
</JetCodeStyleSettings>
|
||||
<Objective-C-extensions>
|
||||
<file>
|
||||
|
@ -73,7 +73,7 @@ play {
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
||||
implementation('io.github.wulkanowy:api:0.6.6') { exclude module: "threetenbp" }
|
||||
implementation('com.github.wulkanowy:api:f941c4b1c7') { exclude module: "threetenbp" }
|
||||
|
||||
implementation "androidx.legacy:legacy-support-v4:1.0.0"
|
||||
implementation "androidx.appcompat:appcompat:1.0.2"
|
||||
@ -82,20 +82,18 @@ dependencies {
|
||||
implementation 'androidx.multidex:multidex:2.0.1'
|
||||
|
||||
implementation 'com.takisoft.preferencex:preferencex:1.0.0'
|
||||
implementation "com.mikepenz:aboutlibraries:6.2.0"
|
||||
implementation "com.firebase:firebase-jobdispatcher:0.8.5"
|
||||
|
||||
implementation "com.google.dagger:dagger-android-support:2.21"
|
||||
kapt "com.google.dagger:dagger-compiler:2.21"
|
||||
kapt "com.google.dagger:dagger-android-processor:2.21"
|
||||
|
||||
implementation "androidx.room:room-runtime:2.1.0-alpha03"
|
||||
implementation "androidx.room:room-rxjava2:2.1.0-alpha03"
|
||||
kapt "androidx.room:room-compiler:2.1.0-alpha03"
|
||||
implementation "androidx.room:room-runtime:2.1.0-alpha04"
|
||||
implementation "androidx.room:room-rxjava2:2.1.0-alpha04"
|
||||
kapt "androidx.room:room-compiler:2.1.0-alpha04"
|
||||
|
||||
implementation "eu.davidea:flexible-adapter:5.1.0"
|
||||
implementation "eu.davidea:flexible-adapter-ui:1.0.0"
|
||||
|
||||
implementation "com.aurelhubert:ahbottomnavigation:2.3.4"
|
||||
implementation 'com.ncapdevi:frag-nav:3.1.0'
|
||||
|
||||
@ -104,16 +102,16 @@ dependencies {
|
||||
implementation "io.reactivex.rxjava2:rxjava:2.2.5"
|
||||
|
||||
implementation "com.jakewharton.threetenabp:threetenabp:1.1.1"
|
||||
|
||||
implementation "com.jakewharton.timber:timber:4.7.1"
|
||||
implementation "at.favre.lib:slf4j-timber:1.0.1"
|
||||
implementation "com.mikepenz:aboutlibraries:6.2.0"
|
||||
|
||||
implementation 'com.google.firebase:firebase-core:16.0.6'
|
||||
implementation 'com.crashlytics.sdk.android:crashlytics:2.9.8'
|
||||
implementation 'com.google.firebase:firebase-core:16.0.7'
|
||||
implementation 'com.crashlytics.sdk.android:crashlytics:2.9.9'
|
||||
|
||||
releaseImplementation 'fr.o80.chucker:library-no-op:2.0.3'
|
||||
debugImplementation 'fr.o80.chucker:library:2.0.3'
|
||||
|
||||
debugImplementation 'fr.o80.chucker:library:2.0.3'
|
||||
debugImplementation "com.amitshekhar.android:debug-db:1.0.4"
|
||||
|
||||
testImplementation "junit:junit:4.12"
|
||||
|
@ -14,10 +14,10 @@ class ApiHelper @Inject constructor(private val api: Api) {
|
||||
symbol = student.symbol
|
||||
schoolSymbol = student.schoolSymbol
|
||||
studentId = student.studentId
|
||||
useNewStudent = false
|
||||
host = URL(student.endpoint).run { host + ":$port".removeSuffix(":-1") }
|
||||
ssl = student.endpoint.startsWith("https")
|
||||
loginType = Api.LoginType.valueOf(student.loginType)
|
||||
useNewStudent = true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.PrimaryKey
|
||||
import java.io.Serializable
|
||||
|
||||
@Entity(tableName = "Students", indices = [Index(value = ["email", "symbol", "student_id", "school_id"], unique = true)])
|
||||
data class Student(
|
||||
@ -35,4 +36,4 @@ data class Student(
|
||||
|
||||
@ColumnInfo(name = "is_current")
|
||||
var isCurrent: Boolean = false
|
||||
)
|
||||
) : Serializable
|
||||
|
@ -24,17 +24,13 @@ class StudentRepository @Inject constructor(
|
||||
val isStudentSaved
|
||||
get() = local.isStudentSaved
|
||||
|
||||
lateinit var cachedStudents: Single<List<Student>>
|
||||
private set
|
||||
|
||||
fun getStudents(email: String, password: String, symbol: String, endpoint: String): Single<List<Student>> {
|
||||
cachedStudents = ReactiveNetwork.checkInternetConnectivity(settings)
|
||||
fun getStudents(email: String, password: String, endpoint: String, symbol: String = ""): Single<List<Student>> {
|
||||
return ReactiveNetwork.checkInternetConnectivity(settings)
|
||||
.flatMap {
|
||||
apiHelper.initApi(email, password, symbol, endpoint)
|
||||
if (it) remote.getStudents(email, password, endpoint)
|
||||
else Single.error(UnknownHostException("No internet connection"))
|
||||
}.doOnSuccess { cachedStudents = Single.just(it) }
|
||||
return cachedStudents
|
||||
}
|
||||
}
|
||||
|
||||
fun getSavedStudents(decryptPass: Boolean = true): Single<List<Student>> {
|
||||
|
@ -25,8 +25,8 @@ class GradeRemote @Inject constructor(private val api: Api) {
|
||||
modifier = it.modifier,
|
||||
comment = it.comment,
|
||||
color = it.color,
|
||||
gradeSymbol = it.symbol ?: "",
|
||||
description = it.description,
|
||||
gradeSymbol = it.symbol.orEmpty(),
|
||||
description = it.description.orEmpty(),
|
||||
weight = it.weight,
|
||||
weightValue = it.weightValue,
|
||||
date = it.date.toLocalDate(),
|
||||
|
@ -10,18 +10,18 @@ import javax.inject.Singleton
|
||||
class StudentRemote @Inject constructor(private val api: Api) {
|
||||
|
||||
fun getStudents(email: String, password: String, endpoint: String): Single<List<Student>> {
|
||||
return api.getPupils().map { students ->
|
||||
students.map { pupil ->
|
||||
return api.getStudents().map { students ->
|
||||
students.map { student ->
|
||||
Student(
|
||||
email = email,
|
||||
password = password,
|
||||
symbol = pupil.symbol,
|
||||
studentId = pupil.studentId,
|
||||
studentName = pupil.studentName,
|
||||
schoolSymbol = pupil.schoolSymbol,
|
||||
schoolName = pupil.description,
|
||||
symbol = student.symbol,
|
||||
studentId = student.studentId,
|
||||
studentName = student.studentName,
|
||||
schoolSymbol = student.schoolSymbol,
|
||||
schoolName = student.schoolName,
|
||||
endpoint = endpoint,
|
||||
loginType = pupil.loginType.name
|
||||
loginType = student.loginType.name
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,11 @@ import dagger.Module
|
||||
import dagger.Provides
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
import io.github.wulkanowy.BuildConfig.DEBUG
|
||||
import io.github.wulkanowy.WulkanowyApp
|
||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||
import io.github.wulkanowy.utils.SchedulersProvider
|
||||
import javax.inject.Named
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@ -34,4 +36,9 @@ internal class AppModule {
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideFirebaseAnalyticsHelper(context: Context) = FirebaseAnalyticsHelper(FirebaseAnalytics.getInstance(context))
|
||||
|
||||
@Singleton
|
||||
@Named("isDebug")
|
||||
@Provides
|
||||
fun provideIsDebug() = DEBUG
|
||||
}
|
||||
|
@ -25,12 +25,12 @@ class AboutPresenter @Inject constructor(
|
||||
when (type) {
|
||||
SPECIAL1 -> {
|
||||
Timber.i("Opening github page")
|
||||
analytics.logEvent("open_page", mapOf("name" to "github"))
|
||||
analytics.logEvent("open_page", "name" to "github")
|
||||
openSourceWebView()
|
||||
}
|
||||
SPECIAL2 -> {
|
||||
Timber.i("Opening issues page")
|
||||
analytics.logEvent("open_page", mapOf("name" to "issues"))
|
||||
analytics.logEvent("open_page", "name" to "issues")
|
||||
openIssuesWebView()
|
||||
}
|
||||
SPECIAL3 -> {
|
||||
|
@ -114,7 +114,7 @@ class AttendancePresenter @Inject constructor(
|
||||
showEmpty(it.isEmpty())
|
||||
showContent(it.isNotEmpty())
|
||||
}
|
||||
analytics.logEvent("load_attendance", mapOf("items" to it.size, "force_refresh" to forceRefresh, START_DATE to currentDate.toFormattedString("yyyy-MM-dd")))
|
||||
analytics.logEvent("load_attendance", "items" to it.size, "force_refresh" to forceRefresh, START_DATE to currentDate.toFormattedString("yyyy-MM-dd"))
|
||||
}) {
|
||||
Timber.i("Loading attendance result: An exception occurred")
|
||||
view?.run { showEmpty(isViewEmpty) }
|
||||
|
@ -83,7 +83,7 @@ class AttendanceSummaryPresenter @Inject constructor(
|
||||
showContent(it.first.isNotEmpty())
|
||||
updateDataSet(it.first, it.second)
|
||||
}
|
||||
analytics.logEvent("load_attendance_summary", mapOf("items" to it.first.size, "force_refresh" to forceRefresh, "item_id" to subjectId))
|
||||
analytics.logEvent("load_attendance_summary", "items" to it.first.size, "force_refresh" to forceRefresh, "item_id" to subjectId)
|
||||
}) {
|
||||
Timber.i("Loading attendance summary result: An exception occurred")
|
||||
view?.run { showEmpty(isViewEmpty) }
|
||||
|
@ -101,7 +101,7 @@ class ExamPresenter @Inject constructor(
|
||||
showEmpty(it.isEmpty())
|
||||
showContent(it.isNotEmpty())
|
||||
}
|
||||
analytics.logEvent("load_exam", mapOf("items" to it.size, "force_refresh" to forceRefresh, START_DATE to currentDate.toFormattedString("yyyy-MM-dd")))
|
||||
analytics.logEvent("load_exam", "items" to it.size, "force_refresh" to forceRefresh, START_DATE to currentDate.toFormattedString("yyyy-MM-dd"))
|
||||
}) {
|
||||
Timber.i("Loading exam result: An exception occurred")
|
||||
view?.run { showEmpty(isViewEmpty) }
|
||||
|
@ -57,7 +57,7 @@ class GradePresenter @Inject constructor(
|
||||
notifyChildrenSemesterChange()
|
||||
loadChild(it.currentPageIndex)
|
||||
}
|
||||
analytics.logEvent("changed_semester", mapOf("number" to index + 1))
|
||||
analytics.logEvent("changed_semester", "number" to index + 1)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ class GradeDetailsPresenter @Inject constructor(
|
||||
showContent(it.isNotEmpty())
|
||||
updateData(it)
|
||||
}
|
||||
analytics.logEvent("load_grade_details", mapOf("items" to it.size, "force_refresh" to forceRefresh))
|
||||
analytics.logEvent("load_grade_details", "items" to it.size, "force_refresh" to forceRefresh)
|
||||
}) {
|
||||
Timber.i("Loading grade details result: An exception occurred")
|
||||
view?.run { showEmpty(isViewEmpty) }
|
||||
|
@ -72,7 +72,7 @@ class GradeSummaryPresenter @Inject constructor(
|
||||
showContent(it.first.isNotEmpty())
|
||||
updateData(it.first, it.second)
|
||||
}
|
||||
analytics.logEvent("load_grade_summary", mapOf("items" to it.first.size, "force_refresh" to forceRefresh))
|
||||
analytics.logEvent("load_grade_summary", "items" to it.first.size, "force_refresh" to forceRefresh)
|
||||
}) {
|
||||
Timber.i("Loading grade summary result: An exception occurred")
|
||||
view?.run { showEmpty(isViewEmpty) }
|
||||
|
@ -86,7 +86,7 @@ class HomeworkPresenter @Inject constructor(
|
||||
showEmpty(it.isEmpty())
|
||||
showContent(it.isNotEmpty())
|
||||
}
|
||||
analytics.logEvent("load_homework", mapOf("items" to it.size, "force_refresh" to forceRefresh, START_DATE to currentDate.toFormattedString("yyyy-MM-dd")))
|
||||
analytics.logEvent("load_homework", "items" to it.size, "force_refresh" to forceRefresh, START_DATE to currentDate.toFormattedString("yyyy-MM-dd"))
|
||||
}) {
|
||||
Timber.i("Loading homework result: An exception occurred")
|
||||
view?.run { showEmpty(isViewEmpty()) }
|
||||
|
@ -4,10 +4,12 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.ui.base.BaseActivity
|
||||
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
|
||||
import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment
|
||||
import io.github.wulkanowy.ui.modules.login.options.LoginOptionsFragment
|
||||
import io.github.wulkanowy.ui.modules.login.studentselect.LoginStudentSelectFragment
|
||||
import io.github.wulkanowy.ui.modules.login.symbol.LoginSymbolFragment
|
||||
import io.github.wulkanowy.utils.setOnSelectPageListener
|
||||
import kotlinx.android.synthetic.main.activity_login.*
|
||||
import javax.inject.Inject
|
||||
@ -38,12 +40,14 @@ class LoginActivity : BaseActivity(), LoginView {
|
||||
override fun initAdapter() {
|
||||
loginAdapter.addFragments(listOf(
|
||||
LoginFormFragment.newInstance(),
|
||||
LoginOptionsFragment.newInstance()
|
||||
LoginSymbolFragment.newInstance(),
|
||||
LoginStudentSelectFragment.newInstance()
|
||||
))
|
||||
|
||||
loginViewpager.run {
|
||||
offscreenPageLimit = 2
|
||||
adapter = loginAdapter
|
||||
setOnSelectPageListener { presenter.onPageSelected(it) }
|
||||
setOnSelectPageListener { presenter.onViewSelected(it) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,22 +55,30 @@ class LoginActivity : BaseActivity(), LoginView {
|
||||
loginViewpager.setCurrentItem(index, false)
|
||||
}
|
||||
|
||||
override fun notifyOptionsViewLoadData() {
|
||||
(loginAdapter.getFragmentInstance(1) as? LoginOptionsFragment)?.onParentLoadData()
|
||||
}
|
||||
|
||||
fun onChildFragmentSwitchOptions() {
|
||||
presenter.onChildViewSwitchOptions()
|
||||
}
|
||||
|
||||
override fun hideActionBar() {
|
||||
supportActionBar?.hide()
|
||||
override fun showActionBar(show: Boolean) {
|
||||
supportActionBar?.apply { if (show) show() else hide() }
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
presenter.onBackPressed { super.onBackPressed() }
|
||||
}
|
||||
|
||||
override fun notifyInitSymbolFragment(loginData: Triple<String, String, String>) {
|
||||
(loginAdapter.getFragmentInstance(1) as? LoginSymbolFragment)?.onParentInitSymbolFragment(loginData)
|
||||
}
|
||||
|
||||
override fun notifyInitStudentSelectFragment(students: List<Student>) {
|
||||
(loginAdapter.getFragmentInstance(2) as? LoginStudentSelectFragment)?.onParentInitStudentSelectFragment(students)
|
||||
}
|
||||
|
||||
fun onFormFragmentAccountLogged(students: List<Student>, loginData: Triple<String, String, String>) {
|
||||
presenter.onFormViewAccountLogged(students, loginData)
|
||||
}
|
||||
|
||||
fun onSymbolFragmentAccountLogged(students: List<Student>) {
|
||||
presenter.onSymbolViewAccountLogged(students)
|
||||
}
|
||||
|
||||
public override fun onDestroy() {
|
||||
presenter.onDetachView()
|
||||
super.onDestroy()
|
||||
|
@ -7,7 +7,8 @@ import io.github.wulkanowy.di.scopes.PerActivity
|
||||
import io.github.wulkanowy.di.scopes.PerFragment
|
||||
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
|
||||
import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment
|
||||
import io.github.wulkanowy.ui.modules.login.options.LoginOptionsFragment
|
||||
import io.github.wulkanowy.ui.modules.login.studentselect.LoginStudentSelectFragment
|
||||
import io.github.wulkanowy.ui.modules.login.symbol.LoginSymbolFragment
|
||||
|
||||
@Module
|
||||
internal abstract class LoginModule {
|
||||
@ -22,10 +23,14 @@ internal abstract class LoginModule {
|
||||
}
|
||||
|
||||
@PerFragment
|
||||
@ContributesAndroidInjector()
|
||||
@ContributesAndroidInjector
|
||||
abstract fun bindLoginFormFragment(): LoginFormFragment
|
||||
|
||||
@PerFragment
|
||||
@ContributesAndroidInjector()
|
||||
abstract fun bindLoginOptionsFragment(): LoginOptionsFragment
|
||||
@ContributesAndroidInjector
|
||||
abstract fun bindLoginSymbolFragment(): LoginSymbolFragment
|
||||
|
||||
@PerFragment
|
||||
@ContributesAndroidInjector
|
||||
abstract fun bindLoginSelectStudentFragment(): LoginStudentSelectFragment
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package io.github.wulkanowy.ui.modules.login
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import timber.log.Timber
|
||||
@ -11,26 +12,49 @@ class LoginPresenter @Inject constructor(errorHandler: ErrorHandler) : BasePrese
|
||||
super.onAttachView(view)
|
||||
view.run {
|
||||
initAdapter()
|
||||
hideActionBar()
|
||||
showActionBar(false)
|
||||
}
|
||||
Timber.i("Login view is attached")
|
||||
}
|
||||
|
||||
fun onPageSelected(index: Int) {
|
||||
if (index == 1) view?.notifyOptionsViewLoadData()
|
||||
fun onFormViewAccountLogged(students: List<Student>, loginData: Triple<String, String, String>) {
|
||||
view?.apply {
|
||||
if (students.isEmpty()) {
|
||||
Timber.i("Switch to symbol form")
|
||||
notifyInitSymbolFragment(loginData)
|
||||
switchView(1)
|
||||
} else {
|
||||
Timber.i("Switch to student select")
|
||||
notifyInitStudentSelectFragment(students)
|
||||
switchView(2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onChildViewSwitchOptions() {
|
||||
view?.switchView(1)
|
||||
fun onSymbolViewAccountLogged(students: List<Student>) {
|
||||
view?.apply {
|
||||
Timber.i("Switch to student select")
|
||||
notifyInitStudentSelectFragment(students)
|
||||
switchView(2)
|
||||
}
|
||||
}
|
||||
|
||||
fun onViewSelected(index: Int) {
|
||||
view?.apply {
|
||||
when (index) {
|
||||
0, 1 -> showActionBar(false)
|
||||
2 -> showActionBar(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onBackPressed(default: () -> Unit) {
|
||||
Timber.i("Back pressed in login view")
|
||||
view?.run {
|
||||
if (currentViewIndex == 1) {
|
||||
switchView(0)
|
||||
hideActionBar()
|
||||
} else default()
|
||||
view?.apply {
|
||||
when (currentViewIndex) {
|
||||
1, 2 -> switchView(0)
|
||||
else -> default()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package io.github.wulkanowy.ui.modules.login
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface LoginView : BaseView {
|
||||
@ -8,9 +9,11 @@ interface LoginView : BaseView {
|
||||
|
||||
fun initAdapter()
|
||||
|
||||
fun hideActionBar()
|
||||
|
||||
fun switchView(index: Int)
|
||||
|
||||
fun notifyOptionsViewLoadData()
|
||||
fun showActionBar(show: Boolean)
|
||||
|
||||
fun notifyInitSymbolFragment(loginData: Triple<String, String, String>)
|
||||
|
||||
fun notifyInitStudentSelectFragment(students: List<Student>)
|
||||
}
|
||||
|
@ -10,9 +10,9 @@ import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo.IME_ACTION_DONE
|
||||
import android.view.inputmethod.EditorInfo.IME_NULL
|
||||
import android.widget.ArrayAdapter
|
||||
import io.github.wulkanowy.BuildConfig.DEBUG
|
||||
import io.github.wulkanowy.BuildConfig.VERSION_NAME
|
||||
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.hideSoftInput
|
||||
@ -29,8 +29,6 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
|
||||
fun newInstance() = LoginFormFragment()
|
||||
}
|
||||
|
||||
override val isDebug = DEBUG
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_login_form, container, false)
|
||||
}
|
||||
@ -41,95 +39,52 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
loginSignButton.setOnClickListener {
|
||||
loginFormSignIn.setOnClickListener {
|
||||
presenter.attemptLogin(
|
||||
loginNicknameEdit.text.toString(),
|
||||
loginPassEdit.text.toString(),
|
||||
loginSymbolEdit.text.toString(),
|
||||
resources.getStringArray(R.array.endpoints_values)[loginHostEdit.selectedItemPosition]
|
||||
loginFormName.text.toString(),
|
||||
loginFormPass.text.toString(),
|
||||
resources.getStringArray(R.array.endpoints_values)[loginFormHost.selectedItemPosition]
|
||||
)
|
||||
}
|
||||
|
||||
loginPassEdit.setOnEditorActionListener { _, id, _ -> onEditAction(id) }
|
||||
loginFormPass.setOnEditorActionListener { _, id, _ ->
|
||||
if (id == IME_ACTION_DONE || id == IME_NULL) loginFormSignIn.callOnClick() else false
|
||||
}
|
||||
|
||||
loginHostEdit.apply {
|
||||
adapter = ArrayAdapter.createFromResource(context, R.array.endpoints_keys, android.R.layout.simple_spinner_item)
|
||||
context?.let {
|
||||
loginFormHost.adapter = ArrayAdapter.createFromResource(it, R.array.endpoints_keys, android.R.layout.simple_spinner_item)
|
||||
.apply { setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) }
|
||||
}
|
||||
|
||||
loginSymbolEdit.run {
|
||||
setAdapter(ArrayAdapter(context, android.R.layout.simple_list_item_1, resources.getStringArray(R.array.symbols_values)))
|
||||
setOnEditorActionListener { _, id, _ -> onEditAction(id) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun showSymbolInput() {
|
||||
loginHeader.text = getString(R.string.login_header_symbol)
|
||||
loginMainForm.visibility = GONE
|
||||
loginSymbolInput.visibility = VISIBLE
|
||||
loginSymbolEdit.requestFocus()
|
||||
showSoftKeyboard()
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun showVersion() {
|
||||
loginVersion.apply {
|
||||
visibility = VISIBLE
|
||||
text = "${getString(R.string.app_name)} $VERSION_NAME"
|
||||
}
|
||||
}
|
||||
|
||||
override fun switchOptionsView() {
|
||||
(activity as? LoginActivity)?.onChildFragmentSwitchOptions()
|
||||
}
|
||||
|
||||
override fun setErrorNicknameRequired() {
|
||||
loginNicknameEdit.run {
|
||||
override fun setErrorNameRequired() {
|
||||
loginFormName.run {
|
||||
requestFocus()
|
||||
error = getString(R.string.login_field_required)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setErrorPassRequired(focus: Boolean) {
|
||||
loginPassEdit.run {
|
||||
loginFormPass.run {
|
||||
if (focus) requestFocus()
|
||||
error = getString(R.string.login_field_required)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setErrorPassInvalid(focus: Boolean) {
|
||||
loginPassEdit.run {
|
||||
loginFormPass.run {
|
||||
if (focus) requestFocus()
|
||||
error = getString(R.string.login_invalid_password)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setErrorSymbolRequire() {
|
||||
loginSymbolEdit.run {
|
||||
requestFocus()
|
||||
error = getString(R.string.login_field_required)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setErrorPassIncorrect() {
|
||||
loginPassEdit.run {
|
||||
loginFormPass.run {
|
||||
requestFocus()
|
||||
error = getString(R.string.login_incorrect_password)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setErrorSymbolIncorrect() {
|
||||
loginSymbolEdit.run {
|
||||
requestFocus()
|
||||
error = getString(R.string.login_incorrect_symbol)
|
||||
}
|
||||
}
|
||||
|
||||
override fun resetViewErrors() {
|
||||
loginNicknameEdit.error = null
|
||||
loginPassEdit.error = null
|
||||
}
|
||||
|
||||
override fun showSoftKeyboard() {
|
||||
activity?.showSoftInput()
|
||||
}
|
||||
@ -146,13 +101,22 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
|
||||
loginFormContainer.visibility = if (show) VISIBLE else GONE
|
||||
}
|
||||
|
||||
private fun onEditAction(actionId: Int): Boolean {
|
||||
return when (actionId) {
|
||||
IME_ACTION_DONE, IME_NULL -> loginSignButton.callOnClick()
|
||||
else -> false
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun showVersion() {
|
||||
loginFormVersion.apply {
|
||||
visibility = VISIBLE
|
||||
text = "${getString(R.string.app_name)} $VERSION_NAME"
|
||||
}
|
||||
}
|
||||
|
||||
override fun notifyParentAccountLogged(students: List<Student>) {
|
||||
(activity as? LoginActivity)?.onFormFragmentAccountLogged(students, Triple(
|
||||
loginFormName.text.toString(),
|
||||
loginFormPass.text.toString(),
|
||||
resources.getStringArray(R.array.endpoints_values)[loginFormHost.selectedItemPosition]
|
||||
))
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
presenter.onDetachView()
|
||||
|
@ -1,7 +1,5 @@
|
||||
package io.github.wulkanowy.ui.modules.login.form
|
||||
|
||||
import com.google.firebase.analytics.FirebaseAnalytics.Event.SIGN_UP
|
||||
import com.google.firebase.analytics.FirebaseAnalytics.Param.GROUP_ID
|
||||
import com.google.firebase.analytics.FirebaseAnalytics.Param.SUCCESS
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
@ -10,16 +8,16 @@ import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||
import io.github.wulkanowy.utils.SchedulersProvider
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Named
|
||||
|
||||
class LoginFormPresenter @Inject constructor(
|
||||
private val schedulers: SchedulersProvider,
|
||||
private val errorHandler: LoginErrorHandler,
|
||||
private val studentRepository: StudentRepository,
|
||||
private val analytics: FirebaseAnalyticsHelper
|
||||
private val analytics: FirebaseAnalyticsHelper,
|
||||
@param:Named("isDebug") private val isDebug: Boolean
|
||||
) : BasePresenter<LoginFormView>(errorHandler) {
|
||||
|
||||
private var wasEmpty = false
|
||||
|
||||
override fun onAttachView(view: LoginFormView) {
|
||||
super.onAttachView(view)
|
||||
view.run {
|
||||
@ -33,10 +31,10 @@ class LoginFormPresenter @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun attemptLogin(email: String, password: String, symbol: String, endpoint: String) {
|
||||
if (!validateCredentials(email, password, symbol)) return
|
||||
fun attemptLogin(email: String, password: String, endpoint: String) {
|
||||
if (!validateCredentials(email, password)) return
|
||||
|
||||
disposable.add(studentRepository.getStudents(email, password, symbol, endpoint)
|
||||
disposable.add(studentRepository.getStudents(email, password, endpoint)
|
||||
.subscribeOn(schedulers.backgroundThread)
|
||||
.observeOn(schedulers.mainThread)
|
||||
.doOnSubscribe {
|
||||
@ -54,35 +52,21 @@ class LoginFormPresenter @Inject constructor(
|
||||
}
|
||||
}
|
||||
.subscribe({
|
||||
view?.run {
|
||||
if (it.isEmpty() && !wasEmpty) {
|
||||
showSymbolInput()
|
||||
wasEmpty = true
|
||||
analytics.logEvent("sign_up_send", mapOf(SUCCESS to false, "students" to 0, "endpoint" to endpoint, GROUP_ID to symbol.ifEmpty { "null" }))
|
||||
Timber.i("Login result: Empty student list")
|
||||
} else if (it.isEmpty() && wasEmpty) {
|
||||
showSymbolInput()
|
||||
setErrorSymbolIncorrect()
|
||||
analytics.logEvent("sign_up_send", mapOf(SUCCESS to false, "students" to it.size, "endpoint" to endpoint, GROUP_ID to symbol.ifEmpty { "null" }))
|
||||
Timber.i("Login result: Wrong symbol")
|
||||
} else {
|
||||
analytics.logEvent("sign_up_send", mapOf(SUCCESS to true, "students" to it.size, "endpoint" to endpoint, GROUP_ID to symbol))
|
||||
Timber.i("Login result: Success")
|
||||
switchOptionsView()
|
||||
}
|
||||
}
|
||||
Timber.i("Login result: Success")
|
||||
analytics.logEvent("registration_form", SUCCESS to true, "students" to it.size, "endpoint" to endpoint, "error" to "No error")
|
||||
view?.notifyParentAccountLogged(it)
|
||||
}, {
|
||||
analytics.logEvent(SIGN_UP, mapOf(SUCCESS to false, "endpoint" to endpoint, "message" to it.localizedMessage, GROUP_ID to symbol.ifEmpty { "null" }))
|
||||
Timber.i("Login result: An exception occurred")
|
||||
analytics.logEvent("registration_form", SUCCESS to false, "students" to -1, "endpoint" to endpoint, "error" to it.localizedMessage)
|
||||
errorHandler.dispatch(it)
|
||||
}))
|
||||
}
|
||||
|
||||
private fun validateCredentials(login: String, password: String, symbol: String): Boolean {
|
||||
private fun validateCredentials(login: String, password: String): Boolean {
|
||||
var isCorrect = true
|
||||
|
||||
if (login.isEmpty()) {
|
||||
view?.setErrorNicknameRequired()
|
||||
view?.setErrorNameRequired()
|
||||
isCorrect = false
|
||||
}
|
||||
|
||||
@ -91,11 +75,6 @@ class LoginFormPresenter @Inject constructor(
|
||||
isCorrect = false
|
||||
}
|
||||
|
||||
if (symbol.isEmpty() && wasEmpty) {
|
||||
view?.setErrorSymbolRequire()
|
||||
isCorrect = false
|
||||
}
|
||||
|
||||
if (password.length < 6 && password.isNotEmpty()) {
|
||||
view?.setErrorPassInvalid(focus = isCorrect)
|
||||
isCorrect = false
|
||||
|
@ -1,31 +1,20 @@
|
||||
package io.github.wulkanowy.ui.modules.login.form
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface LoginFormView : BaseView {
|
||||
|
||||
val isDebug: Boolean
|
||||
|
||||
fun initView()
|
||||
|
||||
fun switchOptionsView()
|
||||
|
||||
fun setErrorNicknameRequired()
|
||||
fun setErrorNameRequired()
|
||||
|
||||
fun setErrorPassRequired(focus: Boolean)
|
||||
|
||||
fun setErrorSymbolRequire()
|
||||
|
||||
fun setErrorPassInvalid(focus: Boolean)
|
||||
|
||||
fun setErrorPassIncorrect()
|
||||
|
||||
fun setErrorSymbolIncorrect()
|
||||
|
||||
fun resetViewErrors()
|
||||
|
||||
fun showVersion()
|
||||
|
||||
fun showSoftKeyboard()
|
||||
|
||||
fun hideSoftKeyboard()
|
||||
@ -34,5 +23,7 @@ interface LoginFormView : BaseView {
|
||||
|
||||
fun showContent(show: Boolean)
|
||||
|
||||
fun showSymbolInput()
|
||||
fun showVersion()
|
||||
|
||||
fun notifyParentAccountLogged(students: List<Student>)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package io.github.wulkanowy.ui.modules.login.options
|
||||
package io.github.wulkanowy.ui.modules.login.studentselect
|
||||
|
||||
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
@ -13,31 +13,35 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
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.setOnItemClickListener
|
||||
import kotlinx.android.synthetic.main.fragment_login_options.*
|
||||
import kotlinx.android.synthetic.main.fragment_login_student_select.*
|
||||
import java.io.Serializable
|
||||
import javax.inject.Inject
|
||||
|
||||
class LoginOptionsFragment : BaseFragment(), LoginOptionsView {
|
||||
class LoginStudentSelectFragment : BaseFragment(), LoginStudentSelectView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: LoginOptionsPresenter
|
||||
lateinit var presenter: LoginStudentSelectPresenter
|
||||
|
||||
@Inject
|
||||
lateinit var loginAdapter: FlexibleAdapter<AbstractFlexibleItem<*>>
|
||||
|
||||
companion object {
|
||||
fun newInstance() = LoginOptionsFragment()
|
||||
const val SAVED_STUDENTS = "STUDENTS"
|
||||
|
||||
fun newInstance() = LoginStudentSelectFragment()
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_login_options, container, false)
|
||||
return inflater.inflate(R.layout.fragment_login_student_select, container, false)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
presenter.onAttachView(this)
|
||||
presenter.onAttachView(this, savedInstanceState?.getSerializable(SAVED_STUDENTS))
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
@ -49,11 +53,7 @@ class LoginOptionsFragment : BaseFragment(), LoginOptionsView {
|
||||
}
|
||||
}
|
||||
|
||||
fun onParentLoadData() {
|
||||
presenter.onParentViewLoadData()
|
||||
}
|
||||
|
||||
override fun updateData(data: List<LoginOptionsItem>) {
|
||||
override fun updateData(data: List<LoginStudentSelectItem>) {
|
||||
loginAdapter.updateDataSet(data, true)
|
||||
}
|
||||
|
||||
@ -76,6 +76,15 @@ class LoginOptionsFragment : BaseFragment(), LoginOptionsView {
|
||||
(activity as? AppCompatActivity)?.supportActionBar?.run { if (show) show() else hide() }
|
||||
}
|
||||
|
||||
fun onParentInitStudentSelectFragment(students: List<Student>) {
|
||||
presenter.onParentInitStudentSelectView(students)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putSerializable(SAVED_STUDENTS, presenter.students as Serializable)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
presenter.onDetachView()
|
||||
super.onDestroyView()
|
@ -1,4 +1,4 @@
|
||||
package io.github.wulkanowy.ui.modules.login.options
|
||||
package io.github.wulkanowy.ui.modules.login.studentselect
|
||||
|
||||
import android.view.View
|
||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
||||
@ -10,7 +10,7 @@ import io.github.wulkanowy.data.db.entities.Student
|
||||
import kotlinx.android.extensions.LayoutContainer
|
||||
import kotlinx.android.synthetic.main.item_login_options.view.*
|
||||
|
||||
class LoginOptionsItem(val student: Student) : AbstractFlexibleItem<LoginOptionsItem.ItemViewHolder>() {
|
||||
class LoginStudentSelectItem(val student: Student) : AbstractFlexibleItem<LoginStudentSelectItem.ItemViewHolder>() {
|
||||
|
||||
override fun getLayoutRes(): Int = R.layout.item_login_options
|
||||
|
||||
@ -27,7 +27,7 @@ class LoginOptionsItem(val student: Student) : AbstractFlexibleItem<LoginOptions
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as LoginOptionsItem
|
||||
other as LoginStudentSelectItem
|
||||
|
||||
if (student != other.student) return false
|
||||
|
@ -1,7 +1,5 @@
|
||||
package io.github.wulkanowy.ui.modules.login.options
|
||||
package io.github.wulkanowy.ui.modules.login.studentselect
|
||||
|
||||
import com.google.firebase.analytics.FirebaseAnalytics.Event.SIGN_UP
|
||||
import com.google.firebase.analytics.FirebaseAnalytics.Param.GROUP_ID
|
||||
import com.google.firebase.analytics.FirebaseAnalytics.Param.SUCCESS
|
||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
@ -13,17 +11,20 @@ import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||
import io.github.wulkanowy.utils.SchedulersProvider
|
||||
import io.reactivex.Single
|
||||
import timber.log.Timber
|
||||
import java.io.Serializable
|
||||
import javax.inject.Inject
|
||||
|
||||
class LoginOptionsPresenter @Inject constructor(
|
||||
class LoginStudentSelectPresenter @Inject constructor(
|
||||
private val errorHandler: LoginErrorHandler,
|
||||
private val studentRepository: StudentRepository,
|
||||
private val semesterRepository: SemesterRepository,
|
||||
private val schedulers: SchedulersProvider,
|
||||
private val analytics: FirebaseAnalyticsHelper
|
||||
) : BasePresenter<LoginOptionsView>(errorHandler) {
|
||||
) : BasePresenter<LoginStudentSelectView>(errorHandler) {
|
||||
|
||||
override fun onAttachView(view: LoginOptionsView) {
|
||||
var students = emptyList<Student>()
|
||||
|
||||
fun onAttachView(view: LoginStudentSelectView, students: Serializable?) {
|
||||
super.onAttachView(view)
|
||||
view.run {
|
||||
initView()
|
||||
@ -32,22 +33,29 @@ class LoginOptionsPresenter @Inject constructor(
|
||||
Timber.i("The student already registered in the app was selected")
|
||||
}
|
||||
}
|
||||
|
||||
if (students is List<*> && students.isNotEmpty()) {
|
||||
loadData(students.filterIsInstance<Student>())
|
||||
}
|
||||
}
|
||||
|
||||
fun onParentViewLoadData() {
|
||||
disposable.add(studentRepository.cachedStudents
|
||||
.observeOn(schedulers.mainThread)
|
||||
.subscribeOn(schedulers.backgroundThread)
|
||||
.doOnSubscribe { view?.showActionBar(true) }
|
||||
.subscribe({ view?.updateData(it.map { student -> LoginOptionsItem(student) }) }, { errorHandler.dispatch(it) }))
|
||||
fun onParentInitStudentSelectView(students: List<Student>) {
|
||||
loadData(students)
|
||||
}
|
||||
|
||||
fun onItemSelected(item: AbstractFlexibleItem<*>?) {
|
||||
if (item is LoginOptionsItem) {
|
||||
if (item is LoginStudentSelectItem) {
|
||||
registerStudent(item.student)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadData(students: List<Student>) {
|
||||
this.students = students
|
||||
view?.apply {
|
||||
updateData(students.map { LoginStudentSelectItem(it) })
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerStudent(student: Student) {
|
||||
disposable.add(studentRepository.saveStudent(student)
|
||||
.map { student.apply { id = it } }
|
||||
@ -65,10 +73,11 @@ class LoginOptionsPresenter @Inject constructor(
|
||||
Timber.i("Registration started")
|
||||
}
|
||||
.subscribe({
|
||||
analytics.logEvent(SIGN_UP, mapOf(SUCCESS to true, "endpoint" to student.endpoint, "message" to "Success", GROUP_ID to student.symbol))
|
||||
analytics.logEvent("registration_student_select", SUCCESS to true, "endpoint" to student.endpoint, "symbol" to student.symbol, "error" to "No error")
|
||||
Timber.i("Registration result: Success")
|
||||
view?.openMainView()
|
||||
}, {
|
||||
analytics.logEvent("registration_student_select", SUCCESS to false, "endpoint" to student.endpoint, "symbol" to student.symbol, "error" to it.localizedMessage)
|
||||
Timber.i("Registration result: An exception occurred ")
|
||||
errorHandler.dispatch(it)
|
||||
view?.apply {
|
@ -1,12 +1,12 @@
|
||||
package io.github.wulkanowy.ui.modules.login.options
|
||||
package io.github.wulkanowy.ui.modules.login.studentselect
|
||||
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface LoginOptionsView : BaseView {
|
||||
interface LoginStudentSelectView : BaseView {
|
||||
|
||||
fun initView()
|
||||
|
||||
fun updateData(data: List<LoginOptionsItem>)
|
||||
fun updateData(data: List<LoginStudentSelectItem>)
|
||||
|
||||
fun openMainView()
|
||||
|
@ -0,0 +1,106 @@
|
||||
package io.github.wulkanowy.ui.modules.login.symbol
|
||||
|
||||
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.view.inputmethod.EditorInfo.IME_ACTION_DONE
|
||||
import android.view.inputmethod.EditorInfo.IME_NULL
|
||||
import android.widget.ArrayAdapter
|
||||
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.hideSoftInput
|
||||
import io.github.wulkanowy.utils.showSoftInput
|
||||
import kotlinx.android.synthetic.main.fragment_login_symbol.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class LoginSymbolFragment : BaseFragment(), LoginSymbolView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: LoginSymbolPresenter
|
||||
|
||||
companion object {
|
||||
private const val SAVED_LOGIN_DATA = "LOGIN_DATA"
|
||||
|
||||
fun newInstance() = LoginSymbolFragment()
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_login_symbol, container, false)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
presenter.onAttachView(this, savedInstanceState?.getSerializable(SAVED_LOGIN_DATA))
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
loginSymbolSignIn.setOnClickListener { presenter.attemptLogin(loginSymbolName.text.toString()) }
|
||||
|
||||
loginSymbolName.apply {
|
||||
setOnEditorActionListener { _, id, _ ->
|
||||
if (id == IME_ACTION_DONE || id == IME_NULL) loginSymbolSignIn.callOnClick() else false
|
||||
}
|
||||
setAdapter(ArrayAdapter(context, android.R.layout.simple_list_item_1, resources.getStringArray(R.array.symbols_values)))
|
||||
}
|
||||
}
|
||||
|
||||
fun onParentInitSymbolFragment(loginData: Triple<String, String, String>) {
|
||||
presenter.onParentInitSymbolView(loginData)
|
||||
}
|
||||
|
||||
override fun setErrorSymbolIncorrect() {
|
||||
loginSymbolName.apply {
|
||||
requestFocus()
|
||||
error = getString(R.string.login_incorrect_symbol)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setErrorSymbolRequire() {
|
||||
loginSymbolName.apply {
|
||||
requestFocus()
|
||||
error = getString(R.string.login_field_required)
|
||||
}
|
||||
}
|
||||
|
||||
override fun clearAndFocusSymbol() {
|
||||
loginSymbolName.apply {
|
||||
text = null
|
||||
requestFocus()
|
||||
}
|
||||
}
|
||||
|
||||
override fun showSoftKeyboard() {
|
||||
activity?.showSoftInput()
|
||||
}
|
||||
|
||||
override fun hideSoftKeyboard() {
|
||||
activity?.hideSoftInput()
|
||||
}
|
||||
|
||||
override fun showProgress(show: Boolean) {
|
||||
loginSymbolProgressContainer.visibility = if (show) VISIBLE else GONE
|
||||
}
|
||||
|
||||
override fun showContent(show: Boolean) {
|
||||
loginSymbolContainer.visibility = if (show) VISIBLE else GONE
|
||||
}
|
||||
|
||||
override fun notifyParentAccountLogged(students: List<Student>) {
|
||||
(activity as? LoginActivity)?.onSymbolFragmentAccountLogged(students)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putSerializable(SAVED_LOGIN_DATA, presenter.loginData)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
presenter.onDetachView()
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package io.github.wulkanowy.ui.modules.login.symbol
|
||||
|
||||
import com.google.firebase.analytics.FirebaseAnalytics.Param.SUCCESS
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||
import io.github.wulkanowy.utils.SchedulersProvider
|
||||
import io.reactivex.Single
|
||||
import timber.log.Timber
|
||||
import java.io.Serializable
|
||||
import javax.inject.Inject
|
||||
|
||||
class LoginSymbolPresenter @Inject constructor(
|
||||
private val studentRepository: StudentRepository,
|
||||
private val errorHandler: LoginErrorHandler,
|
||||
private val schedulers: SchedulersProvider,
|
||||
private val analytics: FirebaseAnalyticsHelper
|
||||
) : BasePresenter<LoginSymbolView>(errorHandler) {
|
||||
|
||||
var loginData: Triple<String, String, String>? = null
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun onAttachView(view: LoginSymbolView, savedLoginData: Serializable?) {
|
||||
super.onAttachView(view)
|
||||
view.initView()
|
||||
if (savedLoginData is Triple<*, *, *>) {
|
||||
loginData = savedLoginData as Triple<String, String, String>
|
||||
}
|
||||
}
|
||||
|
||||
fun attemptLogin(symbol: String) {
|
||||
if (symbol.isBlank()) {
|
||||
view?.setErrorSymbolRequire()
|
||||
return
|
||||
}
|
||||
|
||||
disposable.add(
|
||||
Single.fromCallable { if (loginData == null) throw IllegalArgumentException("Login data is null") else loginData }
|
||||
.flatMap { studentRepository.getStudents(it.first, it.second, it.third, symbol) }
|
||||
.subscribeOn(schedulers.backgroundThread)
|
||||
.observeOn(schedulers.mainThread)
|
||||
.doOnSubscribe {
|
||||
view?.apply {
|
||||
hideSoftKeyboard()
|
||||
showProgress(true)
|
||||
showContent(false)
|
||||
}
|
||||
Timber.i("Login with symbol started")
|
||||
}
|
||||
.doFinally {
|
||||
view?.apply {
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
}
|
||||
}
|
||||
.subscribe({
|
||||
analytics.logEvent("registration_symbol", SUCCESS to true, "students" to it.size, "endpoint" to loginData?.third, "symbol" to symbol, "error" to "No error")
|
||||
view?.apply {
|
||||
if (it.isEmpty()) {
|
||||
Timber.i("Login with symbol result: Empty student list")
|
||||
setErrorSymbolIncorrect()
|
||||
} else {
|
||||
Timber.i("Login with symbol result: Success")
|
||||
notifyParentAccountLogged(it)
|
||||
}
|
||||
}
|
||||
}, {
|
||||
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.localizedMessage)
|
||||
errorHandler.dispatch(it)
|
||||
}))
|
||||
}
|
||||
|
||||
fun onParentInitSymbolView(loginData: Triple<String, String, String>) {
|
||||
this.loginData = loginData
|
||||
view?.apply {
|
||||
clearAndFocusSymbol()
|
||||
showSoftKeyboard()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package io.github.wulkanowy.ui.modules.login.symbol
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface LoginSymbolView : BaseView {
|
||||
|
||||
fun initView()
|
||||
|
||||
fun setErrorSymbolIncorrect()
|
||||
|
||||
fun setErrorSymbolRequire()
|
||||
|
||||
fun clearAndFocusSymbol()
|
||||
|
||||
fun showSoftKeyboard()
|
||||
|
||||
fun hideSoftKeyboard()
|
||||
|
||||
fun showProgress(show: Boolean)
|
||||
|
||||
fun showContent(show: Boolean)
|
||||
|
||||
fun notifyParentAccountLogged(students: List<Student>)
|
||||
}
|
@ -7,7 +7,6 @@ import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.session.SessionErrorHandler
|
||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||
import io.github.wulkanowy.utils.SchedulersProvider
|
||||
import io.reactivex.MaybeSource
|
||||
import javax.inject.Inject
|
||||
|
||||
class LuckyNumberPresenter @Inject constructor(
|
||||
@ -45,7 +44,7 @@ class LuckyNumberPresenter @Inject constructor(
|
||||
showContent(true)
|
||||
showEmpty(false)
|
||||
}
|
||||
analytics.logEvent("load_lucky_number", mapOf("lucky_number" to it.luckyNumber, "force_refresh" to forceRefresh))
|
||||
analytics.logEvent("load_lucky_number", "lucky_number" to it.luckyNumber, "force_refresh" to forceRefresh)
|
||||
}, {
|
||||
view?.run { showEmpty(isViewEmpty()) }
|
||||
errorHandler.dispatch(it)
|
||||
|
@ -32,12 +32,12 @@ class MainPresenter @Inject constructor(
|
||||
}
|
||||
serviceHelper.startFullSyncService()
|
||||
|
||||
analytics.logEvent(APP_OPEN, mapOf(DESTINATION to when (initMenuIndex) {
|
||||
analytics.logEvent(APP_OPEN, DESTINATION to when (initMenuIndex) {
|
||||
1 -> "Grades"
|
||||
3 -> "Timetable"
|
||||
4 -> "More"
|
||||
else -> "User action"
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
fun onViewChange() {
|
||||
|
@ -48,9 +48,9 @@ class MessagePreviewPresenter @Inject constructor(
|
||||
else setSender(it.sender)
|
||||
}
|
||||
}
|
||||
analytics.logEvent("load_message_preview", mapOf(START_DATE to message.date?.toFormattedString("yyyy.MM.dd"), "lenght" to message.content?.length))
|
||||
analytics.logEvent("load_message_preview", START_DATE to message.date?.toFormattedString("yyyy.MM.dd"), "lenght" to message.content?.length)
|
||||
}) {
|
||||
Timber.i("Loading message $id preview result: An excception occurred ")
|
||||
Timber.i("Loading message $id preview result: An exception occurred ")
|
||||
view?.showMessageError()
|
||||
errorHandler.dispatch(it)
|
||||
})
|
||||
|
@ -56,7 +56,7 @@ class MessageTabPresenter @Inject constructor(
|
||||
showContent(it.isNotEmpty())
|
||||
updateData(it)
|
||||
}
|
||||
analytics.logEvent("load_messages", mapOf("items" to it.size, "folder" to folder.name))
|
||||
analytics.logEvent("load_messages", "items" to it.size, "folder" to folder.name)
|
||||
}) {
|
||||
Timber.i("Loading $folder message result: An exception occurred")
|
||||
view?.run { showEmpty(isViewEmpty) }
|
||||
|
@ -54,7 +54,7 @@ class NotePresenter @Inject constructor(
|
||||
showEmpty(it.isEmpty())
|
||||
showContent(it.isNotEmpty())
|
||||
}
|
||||
analytics.logEvent("load_note", mapOf("items" to it.size, "force_refresh" to forceRefresh))
|
||||
analytics.logEvent("load_note", "items" to it.size, "force_refresh" to forceRefresh)
|
||||
}, {
|
||||
Timber.i("Loading note result: An exception occurred")
|
||||
view?.run { showEmpty(isViewEmpty) }
|
||||
|
@ -46,6 +46,6 @@ class SettingsPresenter @Inject constructor(
|
||||
chuckCollector.showNotification(preferencesRepository.isShowChuckerNotification)
|
||||
}
|
||||
}
|
||||
analytics.logEvent("setting_changed", mapOf("name" to key))
|
||||
analytics.logEvent("setting_changed", "name" to key)
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ class TimetablePresenter @Inject constructor(
|
||||
showEmpty(it.isEmpty())
|
||||
showContent(it.isNotEmpty())
|
||||
}
|
||||
analytics.logEvent("load_timetable", mapOf("items" to it.size, "force_refresh" to forceRefresh, START_DATE to currentDate.toFormattedString("yyyy-MM-dd")))
|
||||
analytics.logEvent("load_timetable", "items" to it.size, "force_refresh" to forceRefresh, START_DATE to currentDate.toFormattedString("yyyy-MM-dd"))
|
||||
}) {
|
||||
Timber.i("Loading timetable result: An exception occurred")
|
||||
view?.run { showEmpty(isViewEmpty) }
|
||||
|
@ -96,7 +96,7 @@ class TimetableWidgetProvider : AppWidgetProvider() {
|
||||
}
|
||||
button?.also { btn ->
|
||||
if (btn.isNotBlank()) {
|
||||
analytics.logEvent("changed_timetable_widget_day", mapOf("button" to button))
|
||||
analytics.logEvent("changed_timetable_widget_day", "button" to button)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,14 +7,14 @@ import javax.inject.Singleton
|
||||
@Singleton
|
||||
class FirebaseAnalyticsHelper(private val analytics: FirebaseAnalytics) {
|
||||
|
||||
fun logEvent(name: String, params: Map<String, Any?>) {
|
||||
fun logEvent(name: String, vararg params: Pair<String, Any?>) {
|
||||
Bundle().apply {
|
||||
params.forEach {
|
||||
if (it.value == null) return@forEach
|
||||
when (it.value) {
|
||||
is String, is String? -> putString(it.key, it.value as String)
|
||||
is Int, is Int? -> putInt(it.key, it.value as Int)
|
||||
is Boolean, is Boolean? -> putBoolean(it.key, it.value as Boolean)
|
||||
if (it.second == null) return@forEach
|
||||
when (it.second) {
|
||||
is String, is String? -> putString(it.first, it.second as String)
|
||||
is Int, is Int? -> putInt(it.first, it.second as Int)
|
||||
is Boolean, is Boolean? -> putBoolean(it.first, it.second as Boolean)
|
||||
}
|
||||
}
|
||||
analytics.logEvent(name, this)
|
||||
|
@ -1,6 +1,5 @@
|
||||
<RelativeLayout 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">
|
||||
|
||||
@ -34,7 +33,6 @@
|
||||
</RelativeLayout>
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/loginScroll"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="none">
|
||||
@ -49,7 +47,7 @@
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/loginHeader"
|
||||
android:id="@+id/loginFormHeader"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
@ -57,72 +55,48 @@
|
||||
android:text="@string/login_header_default"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/loginMainForm"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:hint="@string/login_nickname_hint">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
android:id="@+id/loginNicknameEdit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textEmailAddress"
|
||||
android:maxLines="1" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:hint="@string/login_password_hint">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
android:id="@+id/loginPassEdit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:imeActionLabel="@string/login_sign_in"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="textPassword"
|
||||
android:maxLines="1"
|
||||
app:fontFamily="sans-serif" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatSpinner
|
||||
android:id="@+id/loginHostEdit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/login_host_hint" />
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/loginSymbolInput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/login_symbol_hint"
|
||||
android:visibility="gone">
|
||||
android:layout_marginBottom="15dp"
|
||||
android:hint="@string/login_nickname_hint">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/loginSymbolEdit"
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
android:id="@+id/loginFormName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textEmailAddress"
|
||||
android:maxLines="1" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:hint="@string/login_password_hint">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
android:id="@+id/loginFormPass"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:imeActionLabel="@string/login_sign_in"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="textAutoComplete"
|
||||
android:inputType="textPassword"
|
||||
android:maxLines="1"
|
||||
tools:ignore="LabelFor" />
|
||||
app:fontFamily="sans-serif" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatSpinner
|
||||
android:id="@+id/loginFormHost"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/login_host_hint" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
android:id="@+id/loginSignButton"
|
||||
android:id="@+id/loginFormSignIn"
|
||||
style="?android:textAppearanceSmall"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@ -134,12 +108,11 @@
|
||||
app:backgroundTint="@color/colorPrimary" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/loginVersion"
|
||||
android:id="@+id/loginFormVersion"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginBottom="30dp"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/second_text"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
@ -18,8 +19,8 @@
|
||||
android:layout_below="@id/loginOptionsProgressText"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:indeterminate="true"
|
||||
android:minHeight="30dp"
|
||||
android:minWidth="220dp" />
|
||||
android:minWidth="220dp"
|
||||
android:minHeight="30dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/loginOptionsProgressText"
|
||||
@ -33,5 +34,7 @@
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/loginOptionsRecycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
android:layout_height="match_parent"
|
||||
tools:itemCount="5"
|
||||
tools:listitem="@layout/item_login_options" />
|
||||
</LinearLayout>
|
88
app/src/main/res/layout/fragment_login_symbol.xml
Normal file
88
app/src/main/res/layout/fragment_login_symbol.xml
Normal file
@ -0,0 +1,88 @@
|
||||
<RelativeLayout 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">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/loginSymbolProgressContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:gravity="center"
|
||||
android:visibility="gone">
|
||||
|
||||
<ProgressBar
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/loginSymbolProgressText"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:indeterminate="true"
|
||||
android:minWidth="220dp"
|
||||
android:minHeight="30dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/loginSymbolProgressText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:text="@string/login_progress" />
|
||||
</RelativeLayout>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="none">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/loginSymbolContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/loginSymbolHeader"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:text="@string/login_header_symbol"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/login_symbol_hint">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/loginSymbolName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:imeActionLabel="@string/login_sign_in"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="textAutoComplete"
|
||||
android:maxLines="1"
|
||||
tools:ignore="LabelFor" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
android:id="@+id/loginSymbolSignIn"
|
||||
style="?android:textAppearanceSmall"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginBottom="30dp"
|
||||
android:text="@string/login_sign_in"
|
||||
android:textColor="@android:color/white"
|
||||
android:textStyle="bold"
|
||||
app:backgroundTint="@color/colorPrimary" />
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</RelativeLayout>
|
@ -1,7 +1,7 @@
|
||||
package io.github.wulkanowy.data.repositories.remote
|
||||
|
||||
import io.github.wulkanowy.api.Api
|
||||
import io.github.wulkanowy.api.register.Pupil
|
||||
import io.github.wulkanowy.api.register.Student
|
||||
import io.reactivex.Single
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
@ -22,8 +22,8 @@ class StudentRemoteTest {
|
||||
|
||||
@Test
|
||||
fun testRemoteAll() {
|
||||
doReturn(Single.just(listOf(Pupil("", "", 1, "test", "", "", "", Api.LoginType.AUTO))))
|
||||
.`when`(mockApi).getPupils()
|
||||
doReturn(Single.just(listOf(Student("", "", 1, "test", "", "", Api.LoginType.AUTO))))
|
||||
.`when`(mockApi).getStudents()
|
||||
|
||||
val students = StudentRemote(mockApi).getStudents("", "", "").blockingGet()
|
||||
assertEquals(1, students.size)
|
||||
|
@ -6,7 +6,6 @@ import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.clearInvocations
|
||||
import org.mockito.Mockito.doReturn
|
||||
import org.mockito.Mockito.never
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@ -32,25 +31,7 @@ class LoginPresenterTest {
|
||||
@Test
|
||||
fun initViewTest() {
|
||||
verify(loginView).initAdapter()
|
||||
verify(loginView).hideActionBar()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onPageSelectedTest() {
|
||||
presenter.onPageSelected(1)
|
||||
verify(loginView).notifyOptionsViewLoadData()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onPageSelectedNeverTest() {
|
||||
presenter.onPageSelected(0)
|
||||
verify(loginView, never()).notifyOptionsViewLoadData()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onSwitchFragmentTest() {
|
||||
presenter.onChildViewSwitchOptions()
|
||||
verify(loginView).switchView(1)
|
||||
verify(loginView).showActionBar(false)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -59,7 +40,6 @@ class LoginPresenterTest {
|
||||
doReturn(1).`when`(loginView).currentViewIndex
|
||||
presenter.onBackPressed { }
|
||||
verify(loginView).switchView(0)
|
||||
verify(loginView).hideActionBar()
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -37,7 +37,7 @@ class LoginFormPresenterTest {
|
||||
fun initPresenter() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
clearInvocations(repository, loginFormView)
|
||||
presenter = LoginFormPresenter(TestSchedulersProvider(), errorHandler, repository, analytics)
|
||||
presenter = LoginFormPresenter(TestSchedulersProvider(), errorHandler, repository, analytics, false)
|
||||
presenter.onAttachView(loginFormView)
|
||||
}
|
||||
|
||||
@ -48,87 +48,70 @@ class LoginFormPresenterTest {
|
||||
|
||||
@Test
|
||||
fun emptyNicknameLoginTest() {
|
||||
presenter.attemptLogin("", "test123", "test", "https://fakelog.cf")
|
||||
presenter.attemptLogin("", "test123", "https://fakelog.cf")
|
||||
|
||||
verify(loginFormView).setErrorNicknameRequired()
|
||||
verify(loginFormView).setErrorNameRequired()
|
||||
verify(loginFormView, never()).setErrorPassRequired(false)
|
||||
verify(loginFormView, never()).setErrorSymbolRequire()
|
||||
verify(loginFormView, never()).setErrorPassInvalid(false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun emptyPassLoginTest() {
|
||||
presenter.attemptLogin("@", "", "test", "https://fakelog.cf")
|
||||
presenter.attemptLogin("@", "", "https://fakelog.cf")
|
||||
|
||||
verify(loginFormView, never()).setErrorNicknameRequired()
|
||||
verify(loginFormView, never()).setErrorNameRequired()
|
||||
verify(loginFormView).setErrorPassRequired(true)
|
||||
verify(loginFormView, never()).setErrorSymbolRequire()
|
||||
verify(loginFormView, never()).setErrorPassInvalid(false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun invalidPassLoginTest() {
|
||||
presenter.attemptLogin("@", "123", "test", "https://fakelog.cf")
|
||||
presenter.attemptLogin("@", "123", "https://fakelog.cf")
|
||||
|
||||
verify(loginFormView, never()).setErrorNicknameRequired()
|
||||
verify(loginFormView, never()).setErrorNameRequired()
|
||||
verify(loginFormView, never()).setErrorPassRequired(true)
|
||||
verify(loginFormView, never()).setErrorSymbolRequire()
|
||||
verify(loginFormView).setErrorPassInvalid(true)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun emptySymbolLoginTest() {
|
||||
doReturn(Single.just(emptyList<Student>()))
|
||||
.`when`(repository).getStudents(anyString(), anyString(), anyString(), anyString())
|
||||
presenter.attemptLogin("@", "123456", "", "https://fakelog.cf")
|
||||
presenter.attemptLogin("@", "123456", "", "https://fakelog.cf")
|
||||
|
||||
verify(loginFormView).setErrorSymbolRequire()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun loginTest() {
|
||||
val studentTest = Student(email = "test@", password = "123", endpoint = "https://fakelog.cf", loginType = "AUTO")
|
||||
doReturn(Single.just(listOf(studentTest)))
|
||||
.`when`(repository).getStudents(anyString(), anyString(), anyString(), anyString())
|
||||
presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf")
|
||||
presenter.attemptLogin("@", "123456", "https://fakelog.cf")
|
||||
|
||||
verify(loginFormView).hideSoftKeyboard()
|
||||
verify(loginFormView).showProgress(true)
|
||||
verify(loginFormView).showProgress(false)
|
||||
verify(loginFormView).showContent(false)
|
||||
verify(loginFormView).showContent(true)
|
||||
verify(loginFormView).switchOptionsView()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun loginEmptyTest() {
|
||||
doReturn(Single.just(emptyList<Student>()))
|
||||
.`when`(repository).getStudents(anyString(), anyString(), anyString(), anyString())
|
||||
presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf")
|
||||
presenter.attemptLogin("@", "123456", "https://fakelog.cf")
|
||||
|
||||
verify(loginFormView).hideSoftKeyboard()
|
||||
verify(loginFormView).showProgress(true)
|
||||
verify(loginFormView).showProgress(false)
|
||||
verify(loginFormView).showContent(false)
|
||||
verify(loginFormView).showContent(true)
|
||||
verify(loginFormView).showSymbolInput()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun loginEmptyTwiceTest() {
|
||||
doReturn(Single.just(emptyList<Student>()))
|
||||
.`when`(repository).getStudents(anyString(), anyString(), anyString(), anyString())
|
||||
presenter.attemptLogin("@", "123456", "", "https://fakelog.cf")
|
||||
presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf")
|
||||
presenter.attemptLogin("@", "123456", "https://fakelog.cf")
|
||||
presenter.attemptLogin("@", "123456", "https://fakelog.cf")
|
||||
|
||||
verify(loginFormView, times(2)).hideSoftKeyboard()
|
||||
verify(loginFormView, times(2)).showProgress(true)
|
||||
verify(loginFormView, times(2)).showProgress(false)
|
||||
verify(loginFormView, times(2)).showContent(false)
|
||||
verify(loginFormView, times(2)).showContent(true)
|
||||
verify(loginFormView, times(2)).showSymbolInput()
|
||||
verify(loginFormView).setErrorSymbolIncorrect()
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -136,7 +119,7 @@ class LoginFormPresenterTest {
|
||||
val testException = RuntimeException("test")
|
||||
doReturn(Single.error<List<Student>>(testException))
|
||||
.`when`(repository).getStudents(anyString(), anyString(), anyString(), anyString())
|
||||
presenter.attemptLogin("@", "123456", "test", "https://fakelog.cf")
|
||||
presenter.attemptLogin("@", "123456", "https://fakelog.cf")
|
||||
|
||||
verify(loginFormView).hideSoftKeyboard()
|
||||
verify(loginFormView).showProgress(true)
|
||||
|
@ -1,4 +1,4 @@
|
||||
package io.github.wulkanowy.ui.modules.login.options
|
||||
package io.github.wulkanowy.ui.modules.login.studentselect
|
||||
|
||||
import io.github.wulkanowy.TestSchedulersProvider
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
@ -17,13 +17,13 @@ import org.mockito.Mockito.doReturn
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
class LoginOptionsPresenterTest {
|
||||
class LoginStudentSelectPresenterTest {
|
||||
|
||||
@Mock
|
||||
lateinit var errorHandler: LoginErrorHandler
|
||||
|
||||
@Mock
|
||||
lateinit var loginOptionsView: LoginOptionsView
|
||||
lateinit var loginStudentSelectView: LoginStudentSelectView
|
||||
|
||||
@Mock
|
||||
lateinit var studentRepository: StudentRepository
|
||||
@ -34,7 +34,7 @@ class LoginOptionsPresenterTest {
|
||||
@Mock
|
||||
lateinit var analytics: FirebaseAnalyticsHelper
|
||||
|
||||
private lateinit var presenter: LoginOptionsPresenter
|
||||
private lateinit var presenter: LoginStudentSelectPresenter
|
||||
|
||||
private val testStudent by lazy { Student(email = "test", password = "test123", endpoint = "https://fakelog.cf", loginType = "AUTO") }
|
||||
|
||||
@ -43,31 +43,15 @@ class LoginOptionsPresenterTest {
|
||||
@Before
|
||||
fun initPresenter() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
clearInvocations(studentRepository, loginOptionsView)
|
||||
clearInvocations(semesterRepository, loginOptionsView)
|
||||
presenter = LoginOptionsPresenter(errorHandler, studentRepository, semesterRepository, TestSchedulersProvider(), analytics)
|
||||
presenter.onAttachView(loginOptionsView)
|
||||
clearInvocations(studentRepository, loginStudentSelectView)
|
||||
clearInvocations(semesterRepository, loginStudentSelectView)
|
||||
presenter = LoginStudentSelectPresenter(errorHandler, studentRepository, semesterRepository, TestSchedulersProvider(), analytics)
|
||||
presenter.onAttachView(loginStudentSelectView, null)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun initViewTest() {
|
||||
verify(loginOptionsView).initView()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun refreshDataTest() {
|
||||
doReturn(Single.just(listOf(testStudent))).`when`(studentRepository).cachedStudents
|
||||
presenter.onParentViewLoadData()
|
||||
verify(loginOptionsView).showActionBar(true)
|
||||
verify(loginOptionsView).updateData(listOf(LoginOptionsItem(testStudent)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun refreshDataErrorTest() {
|
||||
doReturn(Single.error<List<Student>>(testException)).`when`(studentRepository).cachedStudents
|
||||
presenter.onParentViewLoadData()
|
||||
verify(loginOptionsView).showActionBar(true)
|
||||
verify(errorHandler).dispatch(testException)
|
||||
verify(loginStudentSelectView).initView()
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -75,10 +59,10 @@ class LoginOptionsPresenterTest {
|
||||
doReturn(Single.just(1L)).`when`(studentRepository).saveStudent(testStudent)
|
||||
doReturn(Single.just(emptyList<Semester>())).`when`(semesterRepository).getSemesters(testStudent, true)
|
||||
doReturn(Completable.complete()).`when`(studentRepository).switchStudent(testStudent)
|
||||
presenter.onItemSelected(LoginOptionsItem(testStudent))
|
||||
verify(loginOptionsView).showContent(false)
|
||||
verify(loginOptionsView).showProgress(true)
|
||||
verify(loginOptionsView).openMainView()
|
||||
presenter.onItemSelected(LoginStudentSelectItem(testStudent))
|
||||
verify(loginStudentSelectView).showContent(false)
|
||||
verify(loginStudentSelectView).showProgress(true)
|
||||
verify(loginStudentSelectView).openMainView()
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -86,9 +70,9 @@ class LoginOptionsPresenterTest {
|
||||
doReturn(Single.error<Student>(testException)).`when`(studentRepository).saveStudent(testStudent)
|
||||
doReturn(Single.just(emptyList<Semester>())).`when`(semesterRepository).getSemesters(testStudent, true)
|
||||
doReturn(Completable.complete()).`when`(studentRepository).logoutStudent(testStudent)
|
||||
presenter.onItemSelected(LoginOptionsItem(testStudent))
|
||||
verify(loginOptionsView).showContent(false)
|
||||
verify(loginOptionsView).showProgress(true)
|
||||
presenter.onItemSelected(LoginStudentSelectItem(testStudent))
|
||||
verify(loginStudentSelectView).showContent(false)
|
||||
verify(loginStudentSelectView).showProgress(true)
|
||||
verify(errorHandler).dispatch(testException)
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.20'
|
||||
ext.kotlin_version = '1.3.21'
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
@ -9,12 +9,11 @@ buildscript {
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath 'com.android.tools.build:gradle:3.3.0'
|
||||
classpath 'com.android.tools.build:gradle:3.3.1'
|
||||
classpath 'com.google.gms:google-services:4.2.0'
|
||||
classpath "io.fabric.tools:gradle:1.27.0"
|
||||
classpath "com.github.triplet.gradle:play-publisher:2.1.0"
|
||||
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7"
|
||||
classpath 'com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta02'
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user