Login screens: server ur form

This commit is contained in:
Benoit Marty 2019-11-14 15:25:43 +01:00
parent da8d6fb4f4
commit 6525314af8
14 changed files with 304 additions and 112 deletions

View File

@ -33,7 +33,9 @@
</activity-alias>
<activity android:name=".features.home.HomeActivity" />
<activity android:name=".features.login.LoginActivity" />
<activity
android:name=".features.login.LoginActivity"
android:windowSoftInputMode="adjustResize" />
<activity android:name=".features.media.ImageMediaViewerActivity" />
<activity
android:name=".features.rageshake.BugReportActivity"

View File

@ -68,8 +68,8 @@ object ServerUrlsRepository {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getString(HOME_SERVER_URL_PREF,
prefs.getString(DEFAULT_REFERRER_HOME_SERVER_URL_PREF,
getDefaultHomeServerUrl(context))!!)!!
prefs.getString(DEFAULT_REFERRER_HOME_SERVER_URL_PREF,
getDefaultHomeServerUrl(context))!!)!!
}
/**
@ -80,5 +80,5 @@ object ServerUrlsRepository {
/**
* Return default home server url from resources
*/
fun getDefaultHomeServerUrl(context: Context): String = context.getString(R.string.default_hs_server_url)
fun getDefaultHomeServerUrl(context: Context): String = context.getString(R.string.matrix_org_server_url)
}

View File

@ -77,15 +77,18 @@ class LoginActivity : VectorBaseActivity() {
}
}
private fun onSignModeSelected() {
// TODO
}
private fun onServerSelectionDone() = withState(loginViewModel) {
when (it.serverType) {
ServerType.MatrixOrg -> addFragmentToBackstack(R.id.simpleFragmentContainer, LoginSignUpSignInSelectionFragment::class.java)
ServerType.Modular,
ServerType.Other -> Unit // TODO addFragmentToBackstack(R.id.simpleFragmentContainer, LoginEnterHomeServerFragment::class.java)
ServerType.Other -> addFragmentToBackstack(R.id.simpleFragmentContainer, LoginServerUrlFormFragment::class.java)
}
}
private fun onSignModeSelected() = withState(loginViewModel) {
when (it.signMode) {
SignMode.SignUp -> Unit // TODO addFragmentToBackstack(R.id.simpleFragmentContainer, SignUpFragment::class.java)
SignMode.SignIn -> addFragmentToBackstack(R.id.simpleFragmentContainer, LoginFragment::class.java)
}
}

View File

@ -18,20 +18,15 @@ package im.vector.riotx.features.login
import android.os.Bundle
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.Toast
import androidx.core.view.isVisible
import androidx.transition.TransitionManager
import com.airbnb.mvrx.*
import com.jakewharton.rxbinding3.view.focusChanges
import com.jakewharton.rxbinding3.widget.textChanges
import im.vector.riotx.R
import im.vector.riotx.core.extensions.setTextWithColoredPart
import im.vector.riotx.core.extensions.showPassword
import im.vector.riotx.core.utils.openUrlInExternalBrowser
import im.vector.riotx.features.homeserver.ServerUrlsRepository
import io.reactivex.Observable
import io.reactivex.functions.Function3
import io.reactivex.functions.BiFunction
import io.reactivex.rxkotlin.subscribeBy
import kotlinx.android.synthetic.main.fragment_login.*
import javax.inject.Inject
@ -49,41 +44,8 @@ class LoginFragment @Inject constructor() : AbstractLoginFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupNotice()
setupAuthButton()
setupLoginButton()
setupPasswordReveal()
homeServerField.focusChanges()
.subscribe {
if (!it) {
viewModel.handle(LoginAction.UpdateHomeServer(homeServerField.text.toString()))
}
}
.disposeOnDestroyView()
homeServerField.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
viewModel.handle(LoginAction.UpdateHomeServer(homeServerField.text.toString()))
return@setOnEditorActionListener true
}
return@setOnEditorActionListener false
}
val initHsUrl = viewModel.getInitialHomeServerUrl()
if (initHsUrl != null) {
homeServerField.setText(initHsUrl)
} else {
homeServerField.setText(ServerUrlsRepository.getDefaultHomeServerUrl(requireContext()))
}
viewModel.handle(LoginAction.UpdateHomeServer(homeServerField.text.toString()))
}
private fun setupNotice() {
riotx_no_registration_notice.setTextWithColoredPart(R.string.riotx_no_registration_notice, R.string.riotx_no_registration_notice_colored_part)
riotx_no_registration_notice.setOnClickListener {
openUrlInExternalBrowser(requireActivity(), "https://about.riot.im/downloads")
}
}
private fun authenticate() {
@ -93,23 +55,21 @@ class LoginFragment @Inject constructor() : AbstractLoginFragment() {
viewModel.handle(LoginAction.Login(login, password))
}
private fun setupAuthButton() {
private fun setupLoginButton() {
Observable
.combineLatest(
loginField.textChanges().map { it.trim().isNotEmpty() },
passwordField.textChanges().map { it.trim().isNotEmpty() },
homeServerField.textChanges().map { it.trim().isNotEmpty() },
Function3<Boolean, Boolean, Boolean, Boolean> { isLoginNotEmpty, isPasswordNotEmpty, isHomeServerNotEmpty ->
isLoginNotEmpty && isPasswordNotEmpty && isHomeServerNotEmpty
BiFunction<Boolean, Boolean, Boolean> { isLoginNotEmpty, isPasswordNotEmpty ->
isLoginNotEmpty && isPasswordNotEmpty
}
)
.subscribeBy { authenticateButton.isEnabled = it }
.disposeOnDestroyView()
authenticateButton.setOnClickListener { authenticate() }
authenticateButtonSso.setOnClickListener { openSso() }
}
// TODO Move to server selection screen
private fun openSso() {
loginSharedActionViewModel.post(LoginNavigation.OpenSsoLoginFallback)
}
@ -148,7 +108,6 @@ class LoginFragment @Inject constructor() : AbstractLoginFragment() {
loginField.isVisible = false
passwordContainer.isVisible = false
authenticateButton.isVisible = false
authenticateButtonSso.isVisible = false
passwordShown = false
renderPasswordField()
}
@ -158,7 +117,6 @@ class LoginFragment @Inject constructor() : AbstractLoginFragment() {
loginField.isVisible = false
passwordContainer.isVisible = false
authenticateButton.isVisible = false
authenticateButtonSso.isVisible = false
Toast.makeText(requireActivity(), "Authenticate failure: ${state.asyncHomeServerLoginFlowRequest.error}", Toast.LENGTH_LONG).show()
}
is Success -> {
@ -170,7 +128,6 @@ class LoginFragment @Inject constructor() : AbstractLoginFragment() {
loginField.isVisible = true
passwordContainer.isVisible = true
authenticateButton.isVisible = true
authenticateButtonSso.isVisible = false
if (loginField.text.isNullOrBlank() && passwordField.text.isNullOrBlank()) {
// Jump focus to login
loginField.requestFocus()
@ -180,13 +137,11 @@ class LoginFragment @Inject constructor() : AbstractLoginFragment() {
loginField.isVisible = false
passwordContainer.isVisible = false
authenticateButton.isVisible = false
authenticateButtonSso.isVisible = true
}
LoginMode.Unsupported -> {
loginField.isVisible = false
passwordContainer.isVisible = false
authenticateButton.isVisible = false
authenticateButtonSso.isVisible = false
Toast.makeText(requireActivity(), "None of the homeserver login mode is supported by RiotX", Toast.LENGTH_LONG).show()
}
}

View File

@ -21,6 +21,7 @@ import android.view.View
import butterknife.OnClick
import com.airbnb.mvrx.withState
import im.vector.riotx.R
import im.vector.riotx.core.utils.openUrlInExternalBrowser
import kotlinx.android.synthetic.main.fragment_login_server_selection.*
import me.gujun.android.span.span
import javax.inject.Inject
@ -50,6 +51,7 @@ class LoginServerSelectionFragment @Inject constructor() : AbstractLoginFragment
textDecorationLine = "underline"
onClick = {
// TODO
openUrlInExternalBrowser(requireActivity(), "https://example.org")
}
}

View File

@ -0,0 +1,94 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.riotx.features.login
import android.os.Bundle
import android.view.View
import android.view.inputmethod.EditorInfo
import androidx.core.view.isVisible
import butterknife.OnClick
import com.airbnb.mvrx.withState
import com.jakewharton.rxbinding3.widget.textChanges
import im.vector.riotx.R
import im.vector.riotx.core.utils.openUrlInExternalBrowser
import kotlinx.android.synthetic.main.fragment_login_server_url_form.*
import javax.inject.Inject
/**
*
*/
class LoginServerUrlFormFragment @Inject constructor() : AbstractLoginFragment() {
override fun getLayoutResId() = R.layout.fragment_login_server_url_form
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// TODO Import code from Riot to clear error on TIL
loginServerUrlFormHomeServerUrl.textChanges()
.subscribe(
{
loginServerUrlFormHomeServerUrlTil.error = null
},
{
// Ignore error
})
.disposeOnDestroy()
loginServerUrlFormHomeServerUrl.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
submit()
return@setOnEditorActionListener true
}
return@setOnEditorActionListener false
}
}
@OnClick(R.id.loginServerUrlFormLearnMore)
fun learMore() {
// TODO
openUrlInExternalBrowser(requireActivity(), "https://example.org")
}
@OnClick(R.id.loginServerUrlFormSubmit)
fun submit() {
// TODO Static check of homeserver url, empty, malformed, etc.
viewModel.handle(LoginAction.InitWith(LoginConfig(loginServerUrlFormHomeServerUrl.text.toString(), null)))
}
override fun invalidate() = withState(viewModel) { state ->
when (state.serverType) {
ServerType.Modular -> {
loginServerUrlFormIcon.isVisible = true
loginServerUrlFormTitle.text = getString(R.string.login_connect_to_modular)
loginServerUrlFormText.text = getString(R.string.login_server_url_form_modular_text)
loginServerUrlFormLearnMore.isVisible = true
loginServerUrlFormHomeServerUrlTil.hint = getText(R.string.login_server_url_form_modular_hint)
loginServerUrlFormNotice.text = getString(R.string.login_server_url_form_modular_notice)
}
ServerType.Other -> {
loginServerUrlFormIcon.isVisible = false
loginServerUrlFormTitle.text = getString(R.string.login_server_other_title)
loginServerUrlFormText.text = getString(R.string.login_connect_to_a_custom_server)
loginServerUrlFormLearnMore.isVisible = false
loginServerUrlFormHomeServerUrlTil.hint = getText(R.string.login_server_url_form_other_hint)
loginServerUrlFormNotice.text = getString(R.string.login_server_url_form_other_notice)
}
else -> error("This fragment should not be display in matrix.org mode")
}
}
}

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
@ -5,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
@ -21,29 +22,33 @@
<ImageView
android:id="@+id/logoImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/riotx_logo" />
style="@style/LoginTopIcon"
android:layout_gravity="center_horizontal" />
<TextView
android:id="@+id/riotx_no_registration_notice"
android:id="@+id/loginServerTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="32dp"
android:gravity="center"
android:padding="8dp"
android:text="@string/riotx_no_registration_notice"
android:textColor="?vctr_notice_secondary"
android:textSize="15sp" />
android:layout_marginTop="84dp"
android:textAppearance="@style/TextAppearance.Vector.Login.Title"
tools:text="@string/login_signin_to" />
<TextView
android:id="@+id/loginServerChoiceMatrixOrgText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/layout_vertical_margin"
android:gravity="start"
android:text="@string/login_server_matrix_org_text"
android:textAppearance="@style/TextAppearance.Vector.Login.Text.Small" />
<com.google.android.material.textfield.TextInputLayout
style="@style/VectorTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="14dp"
android:hint="@string/auth_user_name_placeholder">
android:layout_marginTop="32dp"
android:hint="@string/auth_user_name_placeholder"
app:errorEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/loginField"
@ -64,7 +69,8 @@
style="@style/VectorTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/auth_password_placeholder">
android:hint="@string/auth_password_placeholder"
app:errorEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/passwordField"
@ -93,44 +99,35 @@
</FrameLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/VectorTextInputLayout"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:hint="@string/settings_home_server">
android:layout_marginTop="22dp"
android:orientation="horizontal">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/homeServerField"
android:layout_width="match_parent"
<com.google.android.material.button.MaterialButton
android:id="@+id/forgetPasswordButton"
style="@style/Style.Vector.Login.Button.Wired"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:imeOptions="actionDone"
android:inputType="textUri"
android:maxLines="1" />
android:layout_gravity="start"
android:text="@string/auth_forgot_password" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/authenticateButton"
style="@style/Style.Vector.Login.Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_gravity="end"
android:text="@string/auth_login"
tools:ignore="RelativeOverlap" />
<com.google.android.material.button.MaterialButton
android:id="@+id/authenticateButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="22dp"
android:text="@string/auth_login" />
<com.google.android.material.button.MaterialButton
android:id="@+id/authenticateButtonSso"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="22dp"
android:text="@string/auth_login_sso"
android:visibility="gone"
tools:visibility="visible" />
</RelativeLayout>
</LinearLayout>
</ScrollView>
</androidx.core.widget.NestedScrollView>
<View
android:id="@+id/touchArea"

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
@ -176,13 +177,13 @@
</im.vector.riotx.core.platform.CheckableConstraintLayout>
<androidx.appcompat.widget.AppCompatButton
<com.google.android.material.button.MaterialButton
android:id="@+id/loginServerSubmit"
style="@style/Style.Vector.Login.Button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/login_server_submit"
android:text="@string/login_continue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"

View File

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/login_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp">
<ImageView
android:id="@+id/logoImageView"
style="@style/LoginTopIcon"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="130dp" />
<ImageView
android:id="@+id/loginServerUrlFormIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_logo_modular" />
<TextView
android:id="@+id/loginServerUrlFormTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="27dp"
android:textAppearance="@style/TextAppearance.Vector.Login.Title"
tools:text="@string/login_connect_to_modular" />
<TextView
android:id="@+id/loginServerUrlFormText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/layout_vertical_margin"
android:gravity="start"
android:textAppearance="@style/TextAppearance.Vector.Login.Text"
tools:text="@string/login_server_url_form_modular_text" />
<TextView
android:id="@+id/loginServerUrlFormLearnMore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="@string/login_server_modular_learn_more"
android:textAppearance="@style/TextAppearance.Vector.Login.Text"
android:textColor="@color/riotx_accent" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/loginServerUrlFormHomeServerUrlTil"
style="@style/VectorTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="26dp"
app:errorEnabled="true"
tools:hint="@string/login_server_url_form_modular_hint">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/loginServerUrlFormHomeServerUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionDone"
android:inputType="textUri"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/loginServerUrlFormNotice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:gravity="start"
android:textAppearance="@style/TextAppearance.Vector.Login.Text.Small"
tools:text="@string/login_server_url_form_modular_notice" />
<com.google.android.material.button.MaterialButton
android:id="@+id/loginServerUrlFormSubmit"
style="@style/Style.Vector.Login.Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="22dp"
android:text="@string/login_continue" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<View
android:id="@+id/touchArea"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="?vctr_waiting_background_color"
android:clickable="true"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_margin="8dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
@ -55,7 +56,7 @@
app:layout_constraintTop_toBottomOf="@+id/loginSignupSigninTitle"
tools:text="@string/login_server_matrix_org_text" />
<androidx.appcompat.widget.AppCompatButton
<com.google.android.material.button.MaterialButton
android:id="@+id/loginSignupSigninSignUp"
style="@style/Style.Vector.Login.Button"
android:layout_width="0dp"
@ -66,7 +67,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/loginSignupSigninText" />
<androidx.appcompat.widget.AppCompatButton
<com.google.android.material.button.MaterialButton
android:id="@+id/loginSignupSigninSignIn"
style="@style/Style.Vector.Login.Button.Wired"
android:layout_width="0dp"

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
@ -103,7 +104,7 @@
app:layout_constraintStart_toEndOf="@id/loginSplashPicto3"
app:layout_constraintTop_toBottomOf="@+id/loginSplashText2" />
<androidx.appcompat.widget.AppCompatButton
<com.google.android.material.button.MaterialButton
android:id="@+id/loginSplashSubmit"
style="@style/Style.Vector.Login.Button"
android:layout_width="0dp"

View File

@ -5,7 +5,6 @@
<!-- server urls -->
<string name="matrix_org_server_url" translatable="false">https://matrix.org</string>
<string name="default_hs_server_url" translatable="false">https://matrix.org</string>
<string name="piwik_server_url" translatable="false">https://piwik.riot.im</string>
<string name="bug_report_url" translatable="false">https://riot.im/bugreports/submit</string>

View File

@ -36,10 +36,20 @@
<string name="login_server_modular_learn_more">Learn more</string>
<string name="login_server_other_title">Other</string>
<string name="login_server_other_text">Custom &amp; advanced settings</string>
<string name="login_server_submit">Continue</string>
<string name="login_continue">Continue</string>
<string name="login_connect_to">Connect to %1$s</string>
<string name="login_connect_to_modular">Connect to Modular</string>
<string name="login_connect_to_a_custom_server">Connect to a custom server</string>
<string name="login_signin_to">Sign in to %1$s</string>
<string name="login_signup">Sign Up</string>
<string name="login_signin">Sign In</string>
<string name="login_server_url_form_modular_hint">Modular Address</string>
<string name="login_server_url_form_other_hint">Address</string>
<string name="login_server_url_form_modular_text">Premium hosting for organisations</string>
<string name="login_server_url_form_other_text"></string>
<string name="login_server_url_form_modular_notice">Enter the address of the Modular Riot or Server you want to use</string>
<string name="login_server_url_form_other_notice">Enter the address of a server or a Riot you want to connect to</string>
</resources>

View File

@ -8,10 +8,12 @@
</style>
<style name="Style.Vector.Login.Button" parent="VectorButtonStyle">
<item name="android:minHeight">52dp</item>
<item name="android:textAllCaps">false</item>
</style>
<style name="Style.Vector.Login.Button.Wired" parent="VectorButtonStyleFlat">
<item name="android:minHeight">52dp</item>
<item name="android:textAllCaps">false</item>
</style>