Skip to content

Commit 6c2d617

Browse files
committed
feat: Change authentication process and remove navigation (#1749)
1 parent d316fa1 commit 6c2d617

File tree

20 files changed

+379
-63
lines changed

20 files changed

+379
-63
lines changed

app/src/fdroid/java/org/fossasia/openevent/general/auth/SmartAuthViewModel.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ class SmartAuthViewModel : ViewModel() {
1515
val progress: LiveData<Boolean> = mutableProgress
1616
private val mutableApiExceptionRequestCodePair = MutableLiveData<Pair<Any, Any>>()
1717
val apiExceptionCodePair: LiveData<Pair<Any, Any>> = mutableApiExceptionRequestCodePair
18+
private val mutableStatus = MutableLiveData<Boolean>()
19+
val isCredentialStored: LiveData<Boolean> = mutableStatus
1820

1921
fun requestCredentials(any: Any) {
2022
return

app/src/main/java/org/fossasia/openevent/general/MainActivity.kt

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import androidx.navigation.NavController
88
import androidx.navigation.fragment.NavHostFragment
99
import androidx.navigation.ui.NavigationUI.setupWithNavController
1010
import kotlinx.android.synthetic.main.activity_main.navigation
11-
import kotlinx.android.synthetic.main.activity_main.navigationAuth
1211
import kotlinx.android.synthetic.main.activity_main.mainFragmentCoordinatorLayout
1312
import org.fossasia.openevent.general.auth.EditProfileFragment
1413
import org.fossasia.openevent.general.auth.RC_CREDENTIALS_READ
@@ -44,7 +43,6 @@ class MainActivity : AppCompatActivity() {
4443

4544
private fun setupBottomNavigationMenu(navController: NavController) {
4645
setupWithNavController(navigation, navController)
47-
setupWithNavController(navigationAuth, navController)
4846

4947
navigation.setOnNavigationItemReselectedListener {
5048
val hostFragment = supportFragmentManager.findFragmentById(R.id.frameContainer)
@@ -64,17 +62,11 @@ class MainActivity : AppCompatActivity() {
6462
R.id.favoriteFragment -> navAnimVisible(navigation, this@MainActivity)
6563
else -> navAnimGone(navigation, this@MainActivity)
6664
}
67-
when (id) {
68-
R.id.loginFragment,
69-
R.id.signUpFragment -> navAnimVisible(navigationAuth, this@MainActivity)
70-
else -> navAnimGone(navigationAuth, this@MainActivity)
71-
}
7265
}
7366

7467
override fun onBackPressed() {
7568
when (currentFragmentId) {
76-
R.id.loginFragment,
77-
R.id.signUpFragment -> {
69+
R.id.authFragment -> {
7870
navController.popBackStack(R.id.eventsFragment, false)
7971
mainFragmentCoordinatorLayout.snackbar(R.string.sign_in_canceled)
8072
}

app/src/main/java/org/fossasia/openevent/general/auth/AuthApi.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package org.fossasia.openevent.general.auth
33
import io.reactivex.Single
44
import org.fossasia.openevent.general.auth.change.ChangeRequestToken
55
import org.fossasia.openevent.general.auth.change.ChangeRequestTokenResponse
6+
import org.fossasia.openevent.general.auth.forgot.Email
67
import org.fossasia.openevent.general.auth.forgot.RequestToken
78
import org.fossasia.openevent.general.auth.forgot.RequestTokenResponse
89
import retrofit2.http.Body
@@ -33,4 +34,7 @@ interface AuthApi {
3334

3435
@POST("upload/image")
3536
fun uploadImage(@Body uploadImage: UploadImage): Single<ImageResponse>
37+
38+
@POST("users/checkEmail")
39+
fun checkEmail(@Body email: Email): Single<CheckEmailResponse>
3640
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package org.fossasia.openevent.general.auth
2+
3+
import android.os.Bundle
4+
import androidx.fragment.app.Fragment
5+
import android.view.LayoutInflater
6+
import android.view.MenuItem
7+
import android.view.View
8+
import android.view.ViewGroup
9+
import androidx.lifecycle.Observer
10+
import androidx.navigation.Navigation
11+
import androidx.navigation.fragment.navArgs
12+
import kotlinx.android.synthetic.main.fragment_auth.view.getStartedButton
13+
import kotlinx.android.synthetic.main.fragment_auth.view.email
14+
import kotlinx.android.synthetic.main.fragment_auth.view.rootLayout
15+
import org.fossasia.openevent.general.BuildConfig
16+
import org.fossasia.openevent.general.PLAY_STORE_BUILD_FLAVOR
17+
import org.fossasia.openevent.general.R
18+
import org.fossasia.openevent.general.utils.Utils
19+
import org.fossasia.openevent.general.utils.Utils.hideSoftKeyboard
20+
import org.fossasia.openevent.general.utils.Utils.show
21+
import org.fossasia.openevent.general.utils.Utils.progressDialog
22+
import org.fossasia.openevent.general.utils.extensions.nonNull
23+
import org.jetbrains.anko.design.longSnackbar
24+
import org.jetbrains.anko.design.snackbar
25+
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
26+
import org.koin.androidx.viewmodel.ext.android.viewModel
27+
28+
class AuthFragment : Fragment() {
29+
private lateinit var rootView: View
30+
private val authViewModel by viewModel<AuthViewModel>()
31+
private val safeArgs: AuthFragmentArgs by navArgs()
32+
private val smartAuthViewModel by sharedViewModel<SmartAuthViewModel>()
33+
34+
override fun onCreate(savedInstanceState: Bundle?) {
35+
super.onCreate(savedInstanceState)
36+
if (BuildConfig.FLAVOR == PLAY_STORE_BUILD_FLAVOR) {
37+
smartAuthViewModel.requestCredentials(SmartAuthUtil.getCredentialsClient(requireActivity()))
38+
smartAuthViewModel.isCredentialStored
39+
.nonNull()
40+
.observe(this, Observer {
41+
if (it) redirectToLogin()
42+
})
43+
}
44+
}
45+
46+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
47+
rootView = inflater.inflate(R.layout.fragment_auth, container, false)
48+
49+
Utils.setToolbar(activity, "", true)
50+
setHasOptionsMenu(true)
51+
52+
val progressDialog = progressDialog(context)
53+
54+
val snackbarMessage = safeArgs.snackbarMessage
55+
if (!snackbarMessage.isNullOrEmpty()) rootView.snackbar(snackbarMessage)
56+
57+
rootView.getStartedButton.setOnClickListener {
58+
hideSoftKeyboard(context, rootView)
59+
authViewModel.checkUser(rootView.email.text.toString())
60+
}
61+
62+
authViewModel.isUserExists
63+
.nonNull()
64+
.observe(viewLifecycleOwner, Observer {
65+
if (it)
66+
redirectToLogin(rootView.email.text.toString())
67+
else
68+
redirectToSignUp()
69+
authViewModel.mutableStatus.postValue(null)
70+
})
71+
72+
authViewModel.progress
73+
.nonNull()
74+
.observe(viewLifecycleOwner, Observer {
75+
progressDialog.show(it)
76+
})
77+
78+
smartAuthViewModel.progress
79+
.nonNull()
80+
.observe(viewLifecycleOwner, Observer {
81+
progressDialog.show(it)
82+
})
83+
84+
authViewModel.error
85+
.nonNull()
86+
.observe(viewLifecycleOwner, Observer {
87+
rootView.rootLayout.longSnackbar(it)
88+
})
89+
90+
return rootView
91+
}
92+
93+
private fun redirectToLogin(email: String = "") {
94+
Navigation.findNavController(rootView)
95+
.navigate(AuthFragmentDirections
96+
.actionAuthToLogIn(email, safeArgs.redirectedFrom)
97+
)
98+
}
99+
100+
private fun redirectToSignUp() {
101+
Navigation.findNavController(rootView)
102+
.navigate(AuthFragmentDirections
103+
.actionAuthToSignUp(rootView.email.text.toString(), safeArgs.redirectedFrom)
104+
)
105+
}
106+
107+
override fun onOptionsItemSelected(item: MenuItem): Boolean {
108+
return when (item.itemId) {
109+
android.R.id.home -> {
110+
activity?.onBackPressed()
111+
true
112+
}
113+
else -> super.onOptionsItemSelected(item)
114+
}
115+
}
116+
}

app/src/main/java/org/fossasia/openevent/general/auth/AuthService.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,8 @@ class AuthService(
8585
val changeRequestToken = ChangeRequestToken(Password(oldPassword, newPassword))
8686
return authApi.changeRequestToken(changeRequestToken)
8787
}
88+
89+
fun checkEmail(email: String): Single<CheckEmailResponse> {
90+
return authApi.checkEmail(Email(email))
91+
}
8892
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.fossasia.openevent.general.auth
2+
3+
import androidx.lifecycle.LiveData
4+
import androidx.lifecycle.MutableLiveData
5+
import androidx.lifecycle.ViewModel
6+
import org.fossasia.openevent.general.R
7+
import io.reactivex.disposables.CompositeDisposable
8+
import io.reactivex.rxkotlin.plusAssign
9+
import org.fossasia.openevent.general.data.Network
10+
import org.fossasia.openevent.general.data.Resource
11+
import org.fossasia.openevent.general.utils.extensions.withDefaultSchedulers
12+
import timber.log.Timber
13+
14+
class AuthViewModel(
15+
private val authService: AuthService,
16+
private val network: Network,
17+
private val resource: Resource
18+
) : ViewModel() {
19+
20+
private val compositeDisposable = CompositeDisposable()
21+
private val mutableProgress = MutableLiveData<Boolean>()
22+
val progress: LiveData<Boolean> = mutableProgress
23+
val mutableStatus = MutableLiveData<Boolean>()
24+
val isUserExists: LiveData<Boolean> = mutableStatus
25+
private val mutableError = MutableLiveData<String>()
26+
val error: LiveData<String> = mutableError
27+
28+
fun checkUser(email: String) {
29+
if (!network.isNetworkConnected()) {
30+
mutableError.value = resource.getString(R.string.no_internet_message)
31+
return
32+
}
33+
compositeDisposable += authService.checkEmail(email)
34+
.withDefaultSchedulers()
35+
.doOnSubscribe {
36+
mutableProgress.value = true
37+
}.doFinally {
38+
mutableProgress.value = false
39+
}.subscribe({
40+
mutableStatus.value = !it.result
41+
Timber.d("Success!")
42+
}, {
43+
mutableError.value = resource.getString(R.string.error)
44+
Timber.d(it, "Failed")
45+
})
46+
}
47+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package org.fossasia.openevent.general.auth
2+
3+
class CheckEmailResponse(
4+
val result: Boolean
5+
)

app/src/main/java/org/fossasia/openevent/general/auth/LoginFragment.kt

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import androidx.fragment.app.Fragment
1313
import androidx.lifecycle.Observer
1414
import androidx.navigation.Navigation.findNavController
1515
import androidx.navigation.fragment.navArgs
16-
import kotlinx.android.synthetic.main.activity_main.navigationAuth
1716
import kotlinx.android.synthetic.main.fragment_login.email
1817
import kotlinx.android.synthetic.main.fragment_login.password
1918
import kotlinx.android.synthetic.main.fragment_login.loginButton
@@ -28,6 +27,10 @@ import kotlinx.android.synthetic.main.fragment_login.view.tick
2827
import org.fossasia.openevent.general.BuildConfig
2928
import org.fossasia.openevent.general.PLAY_STORE_BUILD_FLAVOR
3029
import org.fossasia.openevent.general.R
30+
import org.fossasia.openevent.general.event.EVENT_DETAIL_FRAGMENT
31+
import org.fossasia.openevent.general.notification.NOTIFICATION_FRAGMENT
32+
import org.fossasia.openevent.general.order.ORDERS_FRAGMENT
33+
import org.fossasia.openevent.general.ticket.TICKETS_FRAGMNET
3134
import org.fossasia.openevent.general.utils.Utils
3235
import org.fossasia.openevent.general.utils.Utils.show
3336
import org.fossasia.openevent.general.utils.Utils.hideSoftKeyboard
@@ -55,7 +58,6 @@ class LoginFragment : Fragment() {
5558
val progressDialog = progressDialog(context)
5659
Utils.setToolbar(activity, getString(R.string.login))
5760
setHasOptionsMenu(true)
58-
showSnackbar()
5961

6062
if (loginViewModel.isLoggedIn())
6163
popBackStack()
@@ -65,7 +67,9 @@ class LoginFragment : Fragment() {
6567
hideSoftKeyboard(context, rootView)
6668
}
6769

68-
if (BuildConfig.FLAVOR == PLAY_STORE_BUILD_FLAVOR) {
70+
if (safeArgs.email.isNotEmpty()) {
71+
rootView.email.text = SpannableStringBuilder(safeArgs.email)
72+
} else if (BuildConfig.FLAVOR == PLAY_STORE_BUILD_FLAVOR) {
6973

7074
smartAuthViewModel.requestCredentials(SmartAuthUtil.getCredentialsClient(requireActivity()))
7175

@@ -82,8 +86,8 @@ class LoginFragment : Fragment() {
8286
})
8387

8488
smartAuthViewModel.apiExceptionCodePair.nonNull().observe(viewLifecycleOwner, Observer {
85-
SmartAuthUtil.handleResolvableApiException(
86-
it.first, requireActivity(), it.second)
89+
SmartAuthUtil.handleResolvableApiException(
90+
it.first, requireActivity(), it.second)
8791
})
8892

8993
smartAuthViewModel.progress
@@ -92,6 +96,7 @@ class LoginFragment : Fragment() {
9296
progressDialog.show(it)
9397
})
9498
}
99+
95100
loginViewModel.progress
96101
.nonNull()
97102
.observe(viewLifecycleOwner, Observer {
@@ -143,10 +148,8 @@ class LoginFragment : Fragment() {
143148
rootView.sentEmailLayout.visibility = View.VISIBLE
144149
rootView.loginLayout.visibility = View.GONE
145150
Utils.setToolbar(activity, show = false)
146-
Utils.navAnimGone(activity?.navigationAuth, requireContext())
147151
} else {
148152
Utils.setToolbar(activity, getString(R.string.login))
149-
Utils.navAnimVisible(activity?.navigationAuth, requireContext())
150153
}
151154
})
152155

@@ -165,7 +168,6 @@ class LoginFragment : Fragment() {
165168
rootView.tick.setOnClickListener {
166169
rootView.sentEmailLayout.visibility = View.GONE
167170
Utils.setToolbar(activity, getString(R.string.login))
168-
Utils.navAnimVisible(activity?.navigationAuth, requireContext())
169171
rootView.loginLayout.visibility = View.VISIBLE
170172
}
171173

@@ -189,7 +191,16 @@ class LoginFragment : Fragment() {
189191
}
190192

191193
private fun popBackStack() {
192-
findNavController(rootView).popBackStack()
194+
val destinationId =
195+
when (safeArgs.redirectedFrom) {
196+
PROFILE_FRAGMENT -> R.id.profileFragment
197+
EVENT_DETAIL_FRAGMENT -> R.id.eventDetailsFragment
198+
ORDERS_FRAGMENT -> R.id.orderUnderUserFragment
199+
TICKETS_FRAGMNET -> R.id.ticketsFragment
200+
NOTIFICATION_FRAGMENT -> R.id.notificationFragment
201+
else -> R.id.eventsFragment
202+
}
203+
findNavController(rootView).popBackStack(destinationId, false)
193204
rootView.snackbar(R.string.welcome_back)
194205
}
195206

@@ -200,17 +211,10 @@ class LoginFragment : Fragment() {
200211
override fun onOptionsItemSelected(item: MenuItem): Boolean {
201212
return when (item.itemId) {
202213
android.R.id.home -> {
203-
findNavController(rootView).popBackStack(R.id.eventsFragment, false)
204-
rootView.snackbar(R.string.sign_in_canceled)
214+
activity?.onBackPressed()
205215
true
206216
}
207217
else -> super.onOptionsItemSelected(item)
208218
}
209219
}
210-
211-
private fun showSnackbar() {
212-
safeArgs.snackbarMessage?.let { textSnackbar ->
213-
rootView.loginCoordinatorLayout.snackbar(textSnackbar)
214-
}
215-
}
216220
}

app/src/main/java/org/fossasia/openevent/general/auth/ProfileFragment.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,16 @@ import org.koin.androidx.viewmodel.ext.android.viewModel
3434
import org.fossasia.openevent.general.utils.Utils.setToolbar
3535
import org.jetbrains.anko.design.snackbar
3636

37+
const val PROFILE_FRAGMENT = "profileFragment"
38+
3739
class ProfileFragment : Fragment() {
3840
private val profileViewModel by viewModel<ProfileViewModel>()
3941

4042
private lateinit var rootView: View
4143
private var emailSettings: String? = null
4244

4345
private fun redirectToLogin() {
44-
findNavController(rootView).navigate(ProfileFragmentDirections
45-
.actionProfileToLogin()
46-
)
46+
findNavController(rootView).navigate(ProfileFragmentDirections.actionProfileToAuth(null, PROFILE_FRAGMENT))
4747
}
4848

4949
private fun redirectToEventsFragment() {

0 commit comments

Comments
 (0)