Commit d054236a authored by Filipe de Lima Brito's avatar Filipe de Lima Brito

Merge branch 'layout/finishing-authentication-screens' into feature/show-chat-list-using-sdk

parents 1004d958 3a1d532d
......@@ -34,8 +34,11 @@
<activity
android:name=".app.ChatRoomActivity"
android:theme="@style/AppTheme">
</activity>
android:theme="@style/AppTheme" />
<activity
android:name=".webview.WebViewActivity"
android:theme="@style/AppTheme" />
</application>
</manifest>
\ No newline at end of file
package chat.rocket.android.authentication.di
import android.content.Context
import chat.rocket.android.authentication.presentation.AuthenticationNavigator
import chat.rocket.android.authentication.ui.AuthenticationActivity
import chat.rocket.android.dagger.scope.PerActivity
......@@ -12,7 +13,7 @@ class AuthenticationModule {
@Provides
@PerActivity
fun provideAuthenticationNavigator(activity: AuthenticationActivity) = AuthenticationNavigator(activity)
fun provideAuthenticationNavigator(activity: AuthenticationActivity, context: Context) = AuthenticationNavigator(activity, context)
@Provides
fun provideJob(): Job {
......
......@@ -58,7 +58,6 @@ class LoginPresenter @Inject constructor(private val view: LoginView,
}
}
fun signup() {
navigator.toSignUp(navigator.currentServer!!)
}
fun signup() =
navigator.toSignUp(navigator.currentServer!!)
}
\ No newline at end of file
......@@ -13,9 +13,9 @@ interface LoginView : LoadingView, MessageView, ShakeView {
* [enableLoginByLinkedin], [enableLoginByMeteor], [enableLoginByTwitter] or [enableLoginByGitlab]) for the oauth view.
* If the possibility of login via social accounts exceeds 3 different ways we should set up the FAB ([setupFabListener]) to show the remaining view(s).
*
* @param show True to show the oauth view, false otherwise.
* @param value True to show the oauth view, false otherwise.
*/
fun shouldShowOauthView(show: Boolean)
fun showOauthView(value: Boolean)
/**
* Setups the FloatingActionButton to show more social accounts views (expanding the oauth view interface to show the remaining view(s)).
......@@ -60,7 +60,7 @@ interface LoginView : LoadingView, MessageView, ShakeView {
/**
* Shows the sign up view if the server settings allow the new users registration.
*
* @param show True to show the sign up view, false otherwise.
* @param value True to show the sign up view, false otherwise.
*/
fun shouldShowSignUpView(show: Boolean)
fun showSignUpView(value: Boolean)
}
\ No newline at end of file
......@@ -4,6 +4,7 @@ import DrawableHelper
import android.os.Build
import android.os.Bundle
import android.support.v4.app.Fragment
import android.text.style.ClickableSpan
import android.view.*
import android.widget.ScrollView
import android.widget.Toast
......@@ -12,6 +13,7 @@ import chat.rocket.android.authentication.login.presentation.LoginPresenter
import chat.rocket.android.authentication.login.presentation.LoginView
import chat.rocket.android.helper.AnimationHelper
import chat.rocket.android.helper.KeyboardHelper
import chat.rocket.android.helper.TextHelper
import chat.rocket.android.util.setVisibility
import chat.rocket.android.util.textContent
import dagger.android.support.AndroidSupportInjection
......@@ -22,14 +24,14 @@ class LoginFragment : Fragment(), LoginView {
@Inject lateinit var presenter: LoginPresenter
private val layoutListener = ViewTreeObserver.OnGlobalLayoutListener {
if (KeyboardHelper.isSoftKeyboardShown(scroll_view.rootView)) {
shouldShowOauthView(false)
shouldShowSignUpView(false)
shouldShowLoginButton(true)
showOauthView(false)
showSignUpView(false)
showLoginButton(true)
} else {
if (isEditTextEmpty()) {
shouldShowOauthView(true)
shouldShowSignUpView(true)
shouldShowLoginButton(false)
showOauthView(true)
showSignUpView(true)
showLoginButton(false)
}
}
}
......@@ -45,7 +47,8 @@ class LoginFragment : Fragment(), LoginView {
}
}
lateinit var serverUrl: String
// Todo remove
private lateinit var serverUrl: String
override fun onCreate(savedInstanceState: Bundle?) {
AndroidSupportInjection.inject(this)
......@@ -68,7 +71,7 @@ class LoginFragment : Fragment(), LoginView {
// TODO: THIS IS A PRESENTER CONCERN - REMOVE THAT !
// -------------------------------------------------------------------------------------------------------------------
shouldShowOauthView(true)
showOauthView(true)
// Show the first three social account's ImageButton (REMARK: we must show at maximum *three* views)
enableLoginByFacebook()
......@@ -78,7 +81,8 @@ class LoginFragment : Fragment(), LoginView {
setupFabListener()
// Just an example: if the server allow the new users registration then show the respective interface.
shouldShowSignUpView(true)
setupSignUpListener()
showSignUpView(true)
// -------------------------------------------------------------------------------------------------------------------
button_log_in.setOnClickListener { presenter.authenticate(text_username_or_email, text_password) }
......@@ -92,8 +96,8 @@ class LoginFragment : Fragment(), LoginView {
}
}
override fun shouldShowOauthView(show: Boolean) {
if (show) {
override fun showOauthView(value: Boolean) {
if (value) {
social_accounts_container.setVisibility(true)
button_fab.setVisibility(true)
......@@ -111,13 +115,9 @@ class LoginFragment : Fragment(), LoginView {
override fun setupFabListener() {
button_fab.setOnClickListener({
enableLoginByLinkedin()
enableLoginByMeteor()
enableLoginByTwitter()
enableLoginByGitlab()
button_fab.hide()
showRemainingSocialAccountsView()
scrollToBottom()
hideFab()
})
}
......@@ -149,21 +149,18 @@ class LoginFragment : Fragment(), LoginView {
button_gitlab.setVisibility(true)
}
override fun shouldShowSignUpView(show: Boolean) {
if (show) {
text_new_to_rocket_chat.setVisibility(true)
text_new_to_rocket_chat.setOnClickListener { presenter.signup() }
} else {
text_new_to_rocket_chat.setVisibility(false)
}
override fun showSignUpView(value: Boolean) {
text_new_to_rocket_chat.setVisibility(value)
}
override fun showLoading() {
view_loading.setVisibility(true)
enableUserInput(false)
view_loading.show()
}
override fun hideLoading() {
view_loading.setVisibility(false)
view_loading.hide()
enableUserInput(true)
}
override fun showMessage(message: String) {
......@@ -171,7 +168,7 @@ class LoginFragment : Fragment(), LoginView {
}
override fun shakeView(viewToShake: View) {
AnimationHelper.vibrate(viewToShake.context)
AnimationHelper.vibrateSmartPhone(viewToShake.context)
AnimationHelper.shakeView(viewToShake)
viewToShake.requestFocus()
}
......@@ -188,12 +185,27 @@ class LoginFragment : Fragment(), LoginView {
}
}
private fun shouldShowLoginButton(show: Boolean) {
if (show) {
button_log_in.setVisibility(true)
} else {
button_log_in.setVisibility(false)
private fun showLoginButton(value: Boolean) {
button_log_in.setVisibility(value)
}
private fun setupSignUpListener() {
val signUp = getString(R.string.title_sign_up)
val newToRocketChat = String.format(getString(R.string.msg_new_to_rocket_chat), signUp)
text_new_to_rocket_chat.text = newToRocketChat
val signUpListener = object : ClickableSpan() {
override fun onClick(view: View) = presenter.signup()
}
TextHelper.addLink(text_new_to_rocket_chat, arrayOf(signUp), arrayOf(signUpListener))
}
private fun enableUserInput(value: Boolean) {
button_log_in.isEnabled = value
text_username_or_email.isEnabled = value
text_password.isEnabled = value
}
// Returns true if *all* EditTexts are empty.
......@@ -201,15 +213,18 @@ class LoginFragment : Fragment(), LoginView {
return text_username_or_email.textContent.isBlank() && text_password.textContent.isEmpty()
}
private fun scrollToBottom() {
scroll_view.postDelayed({
scroll_view.fullScroll(ScrollView.FOCUS_DOWN)
private fun showRemainingSocialAccountsView() {
social_accounts_container.postDelayed({
enableLoginByLinkedin()
enableLoginByMeteor()
enableLoginByTwitter()
enableLoginByGitlab()
}, 1000)
}
private fun hideFab() {
button_fab.postDelayed({
button_fab.hide()
}, 1500)
private fun scrollToBottom() {
scroll_view.postDelayed({
scroll_view.fullScroll(ScrollView.FOCUS_DOWN)
}, 1250)
}
}
\ No newline at end of file
......@@ -60,4 +60,12 @@ class SignupPresenter @Inject constructor(private val view: SignupView,
}
}
}
fun termsOfService() {
navigator.toTermsOfService()
}
fun privacyPolicy() {
navigator.toPrivacyPolicy()
}
}
\ No newline at end of file
......@@ -14,7 +14,6 @@ import chat.rocket.android.authentication.twofactor.presentation.TwoFAPresenter
import chat.rocket.android.authentication.twofactor.presentation.TwoFAView
import chat.rocket.android.helper.AnimationHelper
import chat.rocket.android.util.setVisibility
import chat.rocket.android.util.textContent
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_authentication_two_fa.*
import javax.inject.Inject
......@@ -78,7 +77,7 @@ class TwoFAFragment : Fragment(), TwoFAView {
}
override fun shakeView(viewToShake: View) {
AnimationHelper.vibrate(viewToShake.context)
AnimationHelper.vibrateSmartPhone(viewToShake.context)
AnimationHelper.shakeView(viewToShake)
}
......
......@@ -35,7 +35,7 @@ object AnimationHelper {
/**
* Vibrates the smart phone.
*/
fun vibrate(context: Context) {
fun vibrateSmartPhone(context: Context) {
val vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
if (Build.VERSION.SDK_INT >= 26) {
vibrator.vibrate(VibrationEffect.createOneShot(200, VibrationEffect.DEFAULT_AMPLITUDE))
......
package chat.rocket.android.helper
import android.text.SpannableString
import android.text.Spanned
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.widget.TextView
object TextHelper {
/**
* Adds clickable link(s) to a TextView.
*
* @param textView The TextView to add clickable links.
* @param links The TextView content(s) to act as clickable links.
* @param clickableSpans The ClickableSpan(s) to handle the onClick listener.
*/
fun addLink(textView: TextView, links: Array<String>, clickableSpans: Array<ClickableSpan>) {
val spannableString = SpannableString(textView.text)
for (i in links.indices) {
val clickableSpan = clickableSpans[i]
val link = links[i]
val startIndexOfLink = textView.text.indexOf(link)
spannableString.setSpan(clickableSpan, startIndexOfLink, startIndexOfLink + link.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
textView.movementMethod = LinkMovementMethod.getInstance()
textView.setText(spannableString, TextView.BufferType.SPANNABLE)
}
}
\ No newline at end of file
......@@ -19,13 +19,13 @@ fun View.setVisibility(value: Boolean) {
}
var TextView.textContent: String
get() = this.text.toString()
get() = text.toString()
set(value) {
this.text = value
text = value
}
var TextView.hintContent: String
get() = this.hint.toString()
get() = hint.toString()
set(value) {
this.text = value
text = value
}
package chat.rocket.android.webview
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.webkit.WebViewClient
import chat.rocket.android.R
import kotlinx.android.synthetic.main.activity_web_view.*
import kotlinx.android.synthetic.main.app_bar.*
fun Context.webViewIntent(webPageUrl: String): Intent {
return Intent(this, WebViewActivity::class.java).apply {
putExtra(INTENT_WEB_PAGE_URL, webPageUrl)
}
}
private const val INTENT_WEB_PAGE_URL = "web_page_url"
class WebViewActivity : AppCompatActivity() {
private lateinit var webPageUrl: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_web_view)
webPageUrl = intent.getStringExtra(INTENT_WEB_PAGE_URL)
requireNotNull(webPageUrl) { "no web_page_url provided in Intent extras" }
setupToolbar()
}
override fun onResume() {
super.onResume()
setupWebView()
}
override fun onBackPressed() {
if (web_view.canGoBack()) {
web_view.goBack()
} else {
super.onBackPressed()
}
}
private fun setupToolbar() {
toolbar.title = getString(R.string.title_legal_terms)
toolbar.setNavigationIcon(R.drawable.ic_close_white_24dp)
toolbar.setNavigationOnClickListener {
finish()
}
}
@SuppressLint("SetJavaScriptEnabled")
private fun setupWebView() {
web_view.settings.javaScriptEnabled = true
web_view.webViewClient = WebViewClient()
web_view.loadUrl(webPageUrl)
}
}
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".webview.WebViewActivity">
<include
android:id="@+id/layout_app_bar"
layout="@layout/app_bar" />
<WebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/layout_app_bar" />
</RelativeLayout>
\ No newline at end of file
......@@ -5,7 +5,6 @@
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:fillViewport="true"
tools:context=".authentication.login.ui.LoginFragment">
......@@ -46,11 +45,25 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_username_or_email" />
<TextView
android:id="@+id/text_new_to_rocket_chat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/screen_edge_left_and_right_margins"
android:layout_marginStart="@dimen/screen_edge_left_and_right_margins"
android:layout_marginTop="16dp"
android:gravity="center"
android:textColorLink="@color/colorAccent"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_password"
tools:visibility="visible" />
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginTop="16dp"
android:visibility="gone"
app:indicatorName="BallPulseIndicator"
......@@ -65,7 +78,7 @@
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/screen_edge_left_and_right_margins"
android:layout_marginStart="@dimen/screen_edge_left_and_right_margins"
android:layout_marginTop="16dp"
android:layout_marginTop="20dp"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:orientation="vertical"
......@@ -74,7 +87,7 @@
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_password"
app:layout_constraintTop_toBottomOf="@+id/text_new_to_rocket_chat"
tools:visibility="visible">
<TextView
......@@ -178,23 +191,6 @@
app:layout_constraintTop_toBottomOf="@+id/social_accounts_container"
tools:visibility="visible" />
<TextView
android:id="@+id/text_new_to_rocket_chat"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginBottom="16dp"
android:layout_marginEnd="@dimen/screen_edge_left_and_right_margins"
android:layout_marginStart="@dimen/screen_edge_left_and_right_margins"
android:layout_marginTop="16dp"
android:gravity="center"
android:text="@string/msg_new_to_rocket_chat"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/social_accounts_container"
tools:visibility="visible" />
<Button
android:id="@+id/button_log_in"
style="@style/AuthenticationButton"
......
......@@ -84,7 +84,7 @@
android:layout_marginEnd="@dimen/screen_edge_left_and_right_margins"
android:layout_marginStart="@dimen/screen_edge_left_and_right_margins"
android:gravity="center"
android:text="@string/msg_new_user_agreement"
android:textColorLink="@color/colorAccent"
app:layout_constraintBottom_toTopOf="@+id/button_sign_up"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
......
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Titles -->
<string name="title_sign_in_your_server">Faça login no seu servidor</string>
<string name="title_log_in">Entrar</string>
<string name="title_sign_up">Inscreva-se</string>
<string name="title_legal_terms">Termos Legais</string>
<!-- Actions -->
<string name="action_connect">Conectar</string>
<string name="action_send">Enviar</string>
<string name="action_terms_of_service">Termos de Serviço</string>
<string name="action_privacy_policy">Política de Privacidade</string>
<!-- Regular information messages -->
<string name="msg_no_internet_connection">Sem conexão à internet</string>
......@@ -18,8 +20,8 @@
<string name="msg_name_and_surname">nome e sobrenome</string>
<string name="msg_email">email</string>
<string name="msg_or_continue_using_social_accounts">Ou continue através de contas sociais</string>
<string name="msg_new_to_rocket_chat">Novo no Rocket Chat? <font color='#FF1976D2'>Inscreva-se</font></string>
<string name="msg_new_user_agreement">Ao proceder você concorda com nossos\n<font color='#FF1976D2'>Termos de Serviço</font> e <font color='#FF1976D2'>Política de Privacidade</font></string>
<string name="msg_new_to_rocket_chat">Novo no Rocket Chat? %1$s</string>
<string name="msg_new_user_agreement">Ao proceder você concorda com nossos %1$s e %2$s</string>
<string name="msg_2fa_code">Código 2FA</string>
<string name="msg_yesterday">ontem</string>
<string name="msg_message">Messagem</string>
......
......@@ -5,10 +5,13 @@
<string name="title_sign_in_your_server">Sign in your server</string>
<string name="title_log_in">Log in</string>
<string name="title_sign_up">Sign up</string>
<string name="title_legal_terms">Legal Terms</string>
<!-- Actions -->
<string name="action_connect">Connect</string>
<string name="action_send">Send</string>
<string name="action_terms_of_service">Terms of Service</string>
<string name="action_privacy_policy">Privacy Policy</string>
<!-- Regular information messages -->
<string name="msg_no_internet_connection">No internet connection</string>
......@@ -18,8 +21,8 @@
<string name="msg_name_and_surname">name and surname</string>
<string name="msg_email">email</string>
<string name="msg_or_continue_using_social_accounts">Or continue using social accounts</string>
<string name="msg_new_to_rocket_chat">New to Rocket Chat? <font color='#FF1976D2'>Sign up</font></string>
<string name="msg_new_user_agreement">By proceeding you are agreeing to our\n<font color='#FF1976D2'>Terms of Service</font> and <font color='#FF1976D2'>Privacy Policy</font></string>
<string name="msg_new_to_rocket_chat">New to Rocket Chat? %1$s</string>
<string name="msg_new_user_agreement">By proceeding you are agreeing to our\n%1$s and %2$s</string>
<string name="msg_2fa_code">2FA Code</string>
<string name="msg_more_than_ninety_nine_unread_messages" translatable="false">99+</string>
<string name="msg_yesterday">Yesterday</string>
......
......@@ -9,7 +9,9 @@
<item name="android:statusBarColor">@color/colorPrimaryDark</item>
</style>
<style name="AuthenticationTheme" parent="Theme.AppCompat.NoActionBar" />
<style name="AuthenticationTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:statusBarColor">@color/colorPrimaryDark</item>
</style>
<style name="ChatListTheme" parent="AppTheme">
<item name="android:windowTranslucentStatus">true</item>
......
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