Commit 4058b11c authored by Lucio Maciel's avatar Lucio Maciel

Better organize authentication classes, use LifecycleObserver to cancel Jobs on onDestroy

parent 43391e73
...@@ -80,3 +80,9 @@ dependencies { ...@@ -80,3 +80,9 @@ dependencies {
repositories { repositories {
mavenCentral() mavenCentral()
} }
kotlin {
experimental {
coroutines "enable"
}
}
\ No newline at end of file
package chat.rocket.android
import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
abstract class BaseActivity : AppCompatActivity() {
protected fun addFragment(tag: String, layoutId: Int, block: (Unit) -> Fragment) {
val fragment = supportFragmentManager.findFragmentByTag(tag) ?: block(Unit)
supportFragmentManager.beginTransaction().replace(layoutId, fragment, tag).commit()
}
}
\ No newline at end of file
...@@ -6,6 +6,7 @@ import chat.rocket.android.authentication.ui.AuthenticationActivity ...@@ -6,6 +6,7 @@ import chat.rocket.android.authentication.ui.AuthenticationActivity
import chat.rocket.android.dagger.scope.PerActivity import chat.rocket.android.dagger.scope.PerActivity
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import kotlinx.coroutines.experimental.Job
@Module @Module
class AuthenticationModule { class AuthenticationModule {
...@@ -19,4 +20,9 @@ class AuthenticationModule { ...@@ -19,4 +20,9 @@ class AuthenticationModule {
fun provideAuthTokenRepository(): AuthTokenRepository { fun provideAuthTokenRepository(): AuthTokenRepository {
return AuthTokenRepository() return AuthTokenRepository()
} }
@Provides
fun provideJob(): Job {
return Job()
}
} }
package chat.rocket.android.authentication.di
import chat.rocket.android.authentication.presentation.LoginView
import chat.rocket.android.authentication.ui.LoginFragment
import dagger.Module
import dagger.Provides
@Module
class LoginFragmentModule {
@Provides
fun loginView(frag: LoginFragment): LoginView {
return frag
}
}
package chat.rocket.android.authentication.di
import chat.rocket.android.authentication.presentation.SignupView
import chat.rocket.android.authentication.ui.SignupFragment
import dagger.Module
import dagger.Provides
@Module
class SignupFragmentModule {
@Provides
fun signupView(frag: SignupFragment): SignupView {
return frag
}
}
package chat.rocket.android.authentication.di
import chat.rocket.android.authentication.presentation.LoginView
import chat.rocket.android.authentication.presentation.TwoFAView
import chat.rocket.android.authentication.ui.LoginFragment
import chat.rocket.android.authentication.ui.TwoFAFragment
import dagger.Module
import dagger.Provides
@Module
class TwoFAFragmentModule {
@Provides
fun loginView(frag: TwoFAFragment): TwoFAView {
return frag
}
}
package chat.rocket.android.authentication.login.di
import android.arch.lifecycle.LifecycleOwner
import chat.rocket.android.authentication.login.presentation.LoginView
import chat.rocket.android.authentication.login.ui.LoginFragment
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerFragment
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.experimental.Job
@Module
@PerFragment
class LoginFragmentModule {
@Provides
fun loginView(frag: LoginFragment): LoginView {
return frag
}
@Provides
fun provideLifecycleOwner(frag: LoginFragment): LifecycleOwner {
return frag
}
@Provides
fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy {
return CancelStrategy(owner, jobs)
}
}
package chat.rocket.android.authentication.di package chat.rocket.android.authentication.login.di
import chat.rocket.android.authentication.ui.LoginFragment import chat.rocket.android.authentication.login.ui.LoginFragment
import dagger.Module import dagger.Module
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
......
package chat.rocket.android.authentication.presentation package chat.rocket.android.authentication.login.presentation
import chat.rocket.android.authentication.infraestructure.AuthTokenRepository import chat.rocket.android.authentication.infraestructure.AuthTokenRepository
import chat.rocket.common.RocketChatAuthException import chat.rocket.android.authentication.presentation.AuthenticationNavigator
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.util.launchUI
import chat.rocket.common.RocketChatException import chat.rocket.common.RocketChatException
import chat.rocket.common.RocketChatTwoFactorException
import chat.rocket.common.util.PlatformLogger import chat.rocket.common.util.PlatformLogger
import chat.rocket.core.RocketChatClient import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.rest.login import chat.rocket.core.internal.rest.login
import kotlinx.coroutines.experimental.Job
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.launch
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import javax.inject.Inject import javax.inject.Inject
class LoginPresenter @Inject constructor(private val view: LoginView, class LoginPresenter @Inject constructor(private val view: LoginView,
private val strategy: CancelStrategy,
private val navigator: AuthenticationNavigator, private val navigator: AuthenticationNavigator,
private val okHttpClient: OkHttpClient, private val okHttpClient: OkHttpClient,
private val logger: PlatformLogger, private val logger: PlatformLogger,
private val repository: AuthTokenRepository) { private val repository: AuthTokenRepository) {
var job: Job? = null
val client: RocketChatClient = RocketChatClient.create { val client: RocketChatClient = RocketChatClient.create {
httpClient = okHttpClient httpClient = okHttpClient
restUrl = HttpUrl.parse(navigator.currentServer)!! restUrl = HttpUrl.parse(navigator.currentServer)!!
...@@ -31,31 +31,23 @@ class LoginPresenter @Inject constructor(private val view: LoginView, ...@@ -31,31 +31,23 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
fun authenticate(username: String, password: String) { fun authenticate(username: String, password: String) {
// TODO - validate input // TODO - validate input
job = launch(UI) { launchUI(strategy) {
view.showProgress() view.showLoading()
try { try {
val token = client.login(username, password) val token = client.login(username, password)
view.hideProgress()
navigator.toChatList() navigator.toChatList()
} catch (ex: RocketChatException) { } catch (ex: RocketChatException) {
view.hideProgress()
when(ex) { when(ex) {
is RocketChatAuthException -> is RocketChatTwoFactorException ->
if (ex.error?.contentEquals("totp-required") == true) {
navigator.toTwoFA(navigator.currentServer!!, username, password) navigator.toTwoFA(navigator.currentServer!!, username, password)
} else ->
}
view.onLoginError(ex.message) view.onLoginError(ex.message)
} }
} finally {
view.hideLoading()
} }
} }
fun unbind() {
job?.let {
it.cancel()
}.also { null }
} }
fun signup() { fun signup() {
......
package chat.rocket.android.authentication.login.presentation
import chat.rocket.android.core.behaviours.LoadingView
interface LoginView : LoadingView {
fun onLoginError(message: String?)
}
\ No newline at end of file
package chat.rocket.android.authentication.ui package chat.rocket.android.authentication.login.ui
import DrawableHelper import DrawableHelper
import android.app.ProgressDialog import android.app.ProgressDialog
...@@ -10,8 +10,8 @@ import android.widget.ScrollView ...@@ -10,8 +10,8 @@ import android.widget.ScrollView
import android.widget.Toast import android.widget.Toast
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.app.KeyboardHelper import chat.rocket.android.app.KeyboardHelper
import chat.rocket.android.authentication.presentation.LoginPresenter import chat.rocket.android.authentication.login.presentation.LoginPresenter
import chat.rocket.android.authentication.presentation.LoginView import chat.rocket.android.authentication.login.presentation.LoginView
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_authentication_log_in.* import kotlinx.android.synthetic.main.fragment_authentication_log_in.*
import javax.inject.Inject import javax.inject.Inject
...@@ -42,11 +42,6 @@ class LoginFragment : Fragment(), LoginView { ...@@ -42,11 +42,6 @@ class LoginFragment : Fragment(), LoginView {
serverUrl = arguments?.getString(SERVER_URL) ?: "https://open.rocket.chat" serverUrl = arguments?.getString(SERVER_URL) ?: "https://open.rocket.chat"
} }
override fun onDestroy() {
presenter.unbind()
super.onDestroy()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = inflater.inflate(R.layout.fragment_authentication_log_in, container, false) override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = inflater.inflate(R.layout.fragment_authentication_log_in, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
...@@ -201,12 +196,13 @@ class LoginFragment : Fragment(), LoginView { ...@@ -201,12 +196,13 @@ class LoginFragment : Fragment(), LoginView {
}, 1500) }, 1500)
} }
override fun showProgress() { override fun showLoading() {
// TODO - change for a proper progress indicator // TODO - change for a proper progress indicator
progress = ProgressDialog.show(activity, "Authenticating", "Verifying user credentials") progress = ProgressDialog.show(activity, "Authenticating",
"Verifying user credentials", true, true)
} }
override fun hideProgress() { override fun hideLoading() {
progress?.apply { progress?.apply {
cancel() cancel()
} }
......
...@@ -4,9 +4,9 @@ import android.content.Intent ...@@ -4,9 +4,9 @@ import android.content.Intent
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.app.MainActivity import chat.rocket.android.app.MainActivity
import chat.rocket.android.authentication.ui.AuthenticationActivity import chat.rocket.android.authentication.ui.AuthenticationActivity
import chat.rocket.android.authentication.ui.LoginFragment import chat.rocket.android.authentication.login.ui.LoginFragment
import chat.rocket.android.authentication.ui.SignupFragment import chat.rocket.android.authentication.signup.ui.SignupFragment
import chat.rocket.android.authentication.ui.TwoFAFragment import chat.rocket.android.authentication.twofactor.ui.TwoFAFragment
import chat.rocket.android.util.addFragmentBackStack import chat.rocket.android.util.addFragmentBackStack
class AuthenticationNavigator(internal val activity: AuthenticationActivity) { class AuthenticationNavigator(internal val activity: AuthenticationActivity) {
......
package chat.rocket.android.authentication.presentation
interface LoginView {
fun showProgress()
fun hideProgress()
fun onLoginError(message: String?)
}
\ No newline at end of file
package chat.rocket.android.authentication.presentation
interface ServerView
\ No newline at end of file
package chat.rocket.android.authentication.presentation
interface SignupView {
fun showProgress()
fun hideProgress()
fun onSignupError(message: String? = "Unknown error")
}
\ No newline at end of file
package chat.rocket.android.authentication.presentation
interface TwoFAView : LoginView
\ No newline at end of file
package chat.rocket.android.authentication.di package chat.rocket.android.authentication.server.di
import chat.rocket.android.authentication.presentation.ServerView import chat.rocket.android.authentication.server.presentation.ServerView
import chat.rocket.android.authentication.ui.ServerFragment import chat.rocket.android.authentication.server.ui.ServerFragment
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
......
package chat.rocket.android.authentication.di package chat.rocket.android.authentication.server.di
import chat.rocket.android.authentication.ui.ServerFragment import chat.rocket.android.authentication.server.ui.ServerFragment
import dagger.Module import dagger.Module
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
......
package chat.rocket.android.authentication.presentation package chat.rocket.android.authentication.server.presentation
import chat.rocket.android.authentication.presentation.AuthenticationNavigator
import javax.inject.Inject import javax.inject.Inject
class ServerPresenter @Inject constructor(private val view: ServerView, class ServerPresenter @Inject constructor(private val view: ServerView,
......
package chat.rocket.android.authentication.server.presentation
interface ServerView
\ No newline at end of file
package chat.rocket.android.authentication.ui package chat.rocket.android.authentication.server.ui
import android.os.Bundle import android.os.Bundle
import android.support.v4.app.Fragment import android.support.v4.app.Fragment
...@@ -7,8 +7,8 @@ import android.view.View ...@@ -7,8 +7,8 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.WindowManager import android.view.WindowManager
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.authentication.presentation.ServerPresenter import chat.rocket.android.authentication.server.presentation.ServerPresenter
import chat.rocket.android.authentication.presentation.ServerView import chat.rocket.android.authentication.server.presentation.ServerView
import chat.rocket.android.util.ifEmpty import chat.rocket.android.util.ifEmpty
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_authentication_server.* import kotlinx.android.synthetic.main.fragment_authentication_server.*
......
package chat.rocket.android.authentication.signup.di
import android.arch.lifecycle.LifecycleOwner
import chat.rocket.android.authentication.signup.presentation.SignupView
import chat.rocket.android.authentication.signup.ui.SignupFragment
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerFragment
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.experimental.Job
@Module
@PerFragment
class SignupFragmentModule {
@Provides
fun signupView(frag: SignupFragment): SignupView {
return frag
}
@Provides
fun provideLifecycleOwner(frag: SignupFragment): LifecycleOwner {
return frag
}
@Provides
fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy {
return CancelStrategy(owner, jobs)
}
}
package chat.rocket.android.authentication.di package chat.rocket.android.authentication.signup.di
import chat.rocket.android.authentication.ui.SignupFragment import chat.rocket.android.authentication.signup.ui.SignupFragment
import dagger.Module import dagger.Module
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
......
package chat.rocket.android.authentication.presentation package chat.rocket.android.authentication.signup.presentation
import chat.rocket.android.authentication.infraestructure.AuthTokenRepository import chat.rocket.android.authentication.infraestructure.AuthTokenRepository
import chat.rocket.android.authentication.presentation.AuthenticationNavigator
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.util.launchUI
import chat.rocket.common.RocketChatException import chat.rocket.common.RocketChatException
import chat.rocket.common.util.PlatformLogger import chat.rocket.common.util.PlatformLogger
import chat.rocket.core.RocketChatClient import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.rest.login import chat.rocket.core.internal.rest.login
import chat.rocket.core.internal.rest.signup import chat.rocket.core.internal.rest.signup
import kotlinx.coroutines.experimental.Job
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.launch
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
class SignupPresenter @Inject constructor(private val view: SignupView, class SignupPresenter @Inject constructor(private val view: SignupView,
private val strategy: CancelStrategy,
private val navigator: AuthenticationNavigator, private val navigator: AuthenticationNavigator,
private val okHttpClient: OkHttpClient, private val okHttpClient: OkHttpClient,
private val logger: PlatformLogger, private val logger: PlatformLogger,
private val repository: AuthTokenRepository) { private val repository: AuthTokenRepository) {
var job: Job? = null
val client: RocketChatClient = RocketChatClient.create { val client: RocketChatClient = RocketChatClient.create {
httpClient = okHttpClient httpClient = okHttpClient
restUrl = HttpUrl.parse(navigator.currentServer)!! restUrl = HttpUrl.parse(navigator.currentServer)!!
...@@ -32,8 +32,8 @@ class SignupPresenter @Inject constructor(private val view: SignupView, ...@@ -32,8 +32,8 @@ class SignupPresenter @Inject constructor(private val view: SignupView,
fun signup(email: String, name: String, username: String, password: String) { fun signup(email: String, name: String, username: String, password: String) {
// TODO - validate input // TODO - validate input
job = launch(UI) { launchUI(strategy) {
view.showProgress() view.showLoading()
try { try {
val user = client.signup(email, name, username, password) val user = client.signup(email, name, username, password)
...@@ -42,18 +42,12 @@ class SignupPresenter @Inject constructor(private val view: SignupView, ...@@ -42,18 +42,12 @@ class SignupPresenter @Inject constructor(private val view: SignupView,
val token = client.login(username, password) val token = client.login(username, password)
Timber.d("Logged in: $token") Timber.d("Logged in: $token")
view.hideProgress()
navigator.toChatList() navigator.toChatList()
} catch (ex: RocketChatException) { } catch (ex: RocketChatException) {
view.hideProgress()
view.onSignupError(ex.message) view.onSignupError(ex.message)
} finally {
view.hideLoading()
} }
} }
} }
fun unbind() {
job?.let {
it.cancel()
}.also { null }
}
} }
\ No newline at end of file
package chat.rocket.android.authentication.signup.presentation
import chat.rocket.android.core.behaviours.LoadingView
interface SignupView : LoadingView {
fun onSignupError(message: String? = "Unknown error")
}
\ No newline at end of file
package chat.rocket.android.authentication.ui package chat.rocket.android.authentication.signup.ui
import DrawableHelper import DrawableHelper
import android.app.ProgressDialog import android.app.ProgressDialog
...@@ -9,8 +9,8 @@ import android.view.* ...@@ -9,8 +9,8 @@ import android.view.*
import android.widget.Toast import android.widget.Toast
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.app.KeyboardHelper import chat.rocket.android.app.KeyboardHelper
import chat.rocket.android.authentication.presentation.SignupPresenter import chat.rocket.android.authentication.signup.presentation.SignupPresenter
import chat.rocket.android.authentication.presentation.SignupView import chat.rocket.android.authentication.signup.presentation.SignupView
import chat.rocket.android.util.content import chat.rocket.android.util.content
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_authentication_sign_up.* import kotlinx.android.synthetic.main.fragment_authentication_sign_up.*
...@@ -41,11 +41,6 @@ class SignupFragment : Fragment(), SignupView { ...@@ -41,11 +41,6 @@ class SignupFragment : Fragment(), SignupView {
serverUrl = arguments?.getString(SERVER_URL) ?: "https://open.rocket.chat" serverUrl = arguments?.getString(SERVER_URL) ?: "https://open.rocket.chat"
} }
override fun onDestroy() {
presenter.unbind()
super.onDestroy()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = inflater.inflate(R.layout.fragment_authentication_sign_up, container, false) override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = inflater.inflate(R.layout.fragment_authentication_sign_up, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
...@@ -100,12 +95,13 @@ class SignupFragment : Fragment(), SignupView { ...@@ -100,12 +95,13 @@ class SignupFragment : Fragment(), SignupView {
} }
} }
override fun showProgress() { override fun showLoading() {
// TODO - change for a proper progress indicator // TODO - change for a proper progress indicator
progress = ProgressDialog.show(activity, "Authenticating", "Registering user") progress = ProgressDialog.show(activity, "Authenticating",
"Registering user", true, true)
} }
override fun hideProgress() { override fun hideLoading() {
progress?.apply { progress?.apply {
cancel() cancel()
} }
......
package chat.rocket.android.authentication.twofactor.di
import android.arch.lifecycle.LifecycleOwner
import chat.rocket.android.authentication.twofactor.presentation.TwoFAView
import chat.rocket.android.authentication.twofactor.ui.TwoFAFragment
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.dagger.scope.PerFragment
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.experimental.Job
@Module
@PerFragment
class TwoFAFragmentModule {
@Provides
fun loginView(frag: TwoFAFragment): TwoFAView {
return frag
}
@Provides
fun provideLifecycleOwner(frag: TwoFAFragment): LifecycleOwner {
return frag
}
@Provides
fun provideCancelStrategy(owner: LifecycleOwner, jobs: Job): CancelStrategy {
return CancelStrategy(owner, jobs)
}
}
package chat.rocket.android.authentication.di package chat.rocket.android.authentication.twofactor.di
import chat.rocket.android.authentication.ui.TwoFAFragment import chat.rocket.android.authentication.twofactor.ui.TwoFAFragment
import dagger.Module import dagger.Module
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
......
package chat.rocket.android.authentication.presentation package chat.rocket.android.authentication.twofactor.presentation
import chat.rocket.android.authentication.infraestructure.AuthTokenRepository import chat.rocket.android.authentication.infraestructure.AuthTokenRepository
import chat.rocket.android.authentication.presentation.AuthenticationNavigator
import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.util.launchUI
import chat.rocket.common.RocketChatException import chat.rocket.common.RocketChatException
import chat.rocket.common.util.PlatformLogger import chat.rocket.common.util.PlatformLogger
import chat.rocket.core.RocketChatClient import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.rest.login import chat.rocket.core.internal.rest.login
import kotlinx.coroutines.experimental.Job
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.launch
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import javax.inject.Inject import javax.inject.Inject
class TwoFAPresenter @Inject constructor(private val view: TwoFAView, class TwoFAPresenter @Inject constructor(private val view: TwoFAView,
private val strategy: CancelStrategy,
private val navigator: AuthenticationNavigator, private val navigator: AuthenticationNavigator,
private val okHttpClient: OkHttpClient, private val okHttpClient: OkHttpClient,
private val logger: PlatformLogger, private val logger: PlatformLogger,
private val repository: AuthTokenRepository) { private val repository: AuthTokenRepository) {
var job: Job? = null
val client: RocketChatClient = RocketChatClient.create { val client: RocketChatClient = RocketChatClient.create {
httpClient = okHttpClient httpClient = okHttpClient
restUrl = HttpUrl.parse(navigator.currentServer)!! restUrl = HttpUrl.parse(navigator.currentServer)!!
...@@ -30,25 +30,18 @@ class TwoFAPresenter @Inject constructor(private val view: TwoFAView, ...@@ -30,25 +30,18 @@ class TwoFAPresenter @Inject constructor(private val view: TwoFAView,
fun authenticate(username: String, password: String, pin: String) { fun authenticate(username: String, password: String, pin: String) {
// TODO - validate input // TODO - validate input
job = launch(UI) { launchUI(strategy) {
view.showProgress() view.showLoading()
try { try {
val token = client.login(username, password, pin) val token = client.login(username, password, pin)
view.hideProgress()
navigator.toChatList() navigator.toChatList()
} catch (ex: RocketChatException) { } catch (ex: RocketChatException) {
view.hideProgress()
view.onLoginError(ex.message) view.onLoginError(ex.message)
} finally {
view.hideLoading()
} }
} }
}
fun unbind() {
job?.let {
it.cancel()
}.also { null }
} }
fun signup() { fun signup() {
......
package chat.rocket.android.authentication.twofactor.presentation
import chat.rocket.android.authentication.login.presentation.LoginView
interface TwoFAView : LoginView
\ No newline at end of file
package chat.rocket.android.authentication.ui package chat.rocket.android.authentication.twofactor.ui
import DrawableHelper import DrawableHelper
import android.app.ProgressDialog import android.app.ProgressDialog
...@@ -11,8 +11,8 @@ import android.view.ViewGroup ...@@ -11,8 +11,8 @@ import android.view.ViewGroup
import android.view.WindowManager import android.view.WindowManager
import android.widget.Toast import android.widget.Toast
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.authentication.presentation.TwoFAPresenter import chat.rocket.android.authentication.twofactor.presentation.TwoFAPresenter
import chat.rocket.android.authentication.presentation.TwoFAView import chat.rocket.android.authentication.twofactor.presentation.TwoFAView
import chat.rocket.android.util.content import chat.rocket.android.util.content
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_authentication_two_fa.* import kotlinx.android.synthetic.main.fragment_authentication_two_fa.*
...@@ -52,12 +52,6 @@ class TwoFAFragment : Fragment(), TwoFAView { ...@@ -52,12 +52,6 @@ class TwoFAFragment : Fragment(), TwoFAView {
password = arguments?.getString(PASSWORD) ?: "" password = arguments?.getString(PASSWORD) ?: ""
} }
override fun onDestroy() {
presenter.unbind()
super.onDestroy()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = inflater.inflate(R.layout.fragment_authentication_two_fa, container, false) override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = inflater.inflate(R.layout.fragment_authentication_two_fa, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
...@@ -84,12 +78,13 @@ class TwoFAFragment : Fragment(), TwoFAView { ...@@ -84,12 +78,13 @@ class TwoFAFragment : Fragment(), TwoFAView {
} }
} }
override fun showProgress() { override fun showLoading() {
// TODO - change for a proper progress indicator // TODO - change for a proper progress indicator
progress = ProgressDialog.show(activity, "Authenticating", "Verifying user credentials") progress = ProgressDialog.show(activity, "Authenticating",
"Verifying user credentials", true, true)
} }
override fun hideProgress() { override fun hideLoading() {
progress?.apply { progress?.apply {
cancel() cancel()
} }
......
...@@ -5,6 +5,7 @@ import android.support.v4.app.Fragment ...@@ -5,6 +5,7 @@ import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity import android.support.v7.app.AppCompatActivity
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.app.LayoutHelper import chat.rocket.android.app.LayoutHelper
import chat.rocket.android.authentication.server.ui.ServerFragment
import chat.rocket.android.util.addFragment import chat.rocket.android.util.addFragment
import dagger.android.AndroidInjection import dagger.android.AndroidInjection
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
......
package chat.rocket.android.core.behaviours
interface LoadingView {
fun showLoading()
fun hideLoading()
}
\ No newline at end of file
package chat.rocket.android.core.lifecycle
import android.arch.lifecycle.Lifecycle
import android.arch.lifecycle.LifecycleObserver
import android.arch.lifecycle.LifecycleOwner
import android.arch.lifecycle.OnLifecycleEvent
import kotlinx.coroutines.experimental.Job
import javax.inject.Inject
class CancelStrategy @Inject constructor(owner: LifecycleOwner, val jobs: Job) : LifecycleObserver {
init {
owner.lifecycle.addObserver(this)
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
jobs.cancel()
}
}
\ No newline at end of file
...@@ -2,6 +2,10 @@ package chat.rocket.android.dagger.module ...@@ -2,6 +2,10 @@ package chat.rocket.android.dagger.module
import chat.rocket.android.app.MainActivity import chat.rocket.android.app.MainActivity
import chat.rocket.android.authentication.di.* import chat.rocket.android.authentication.di.*
import chat.rocket.android.authentication.login.di.LoginFragmentProvider
import chat.rocket.android.authentication.server.di.ServerFragmentProvider
import chat.rocket.android.authentication.signup.di.SignupFragmentProvider
import chat.rocket.android.authentication.twofactor.di.TwoFAFragmentProvider
import chat.rocket.android.authentication.ui.AuthenticationActivity import chat.rocket.android.authentication.ui.AuthenticationActivity
import chat.rocket.android.dagger.scope.PerActivity import chat.rocket.android.dagger.scope.PerActivity
import dagger.Module import dagger.Module
......
package chat.rocket.android.util
import chat.rocket.android.core.lifecycle.CancelStrategy
import kotlinx.coroutines.experimental.CoroutineScope
import kotlinx.coroutines.experimental.Job
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.launch
/**
* Launches a coroutine on the UI context.
*
* @param strategy a CancelStrategy for canceling the coroutine job
*/
fun launchUI(strategy: CancelStrategy, block: suspend CoroutineScope.() -> Unit): Job {
return launch(context = UI, parent = strategy.jobs, block = block)
}
\ No newline at end of file
...@@ -7,7 +7,7 @@ ext { ...@@ -7,7 +7,7 @@ ext {
targetSdk : 27, targetSdk : 27,
buildTools : '27.0.0', buildTools : '27.0.0',
kotlin : '1.2.0', kotlin : '1.2.0',
coroutine : '0.19.3', coroutine : '0.20',
dokka : '0.9.15', dokka : '0.9.15',
// Main dependencies // Main dependencies
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment