Skip to content

Commit

Permalink
Login fields should support password managers. Closes #99
Browse files Browse the repository at this point in the history
Upping versionCode to 39
  • Loading branch information
Dima-Android committed Jan 9, 2024
1 parent 32f5f30 commit 89d6a13
Show file tree
Hide file tree
Showing 9 changed files with 255 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.zotero.android.androidx.content

import android.graphics.Color.WHITE
import android.view.View
import androidx.annotation.StringRes
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import com.google.android.material.snackbar.Snackbar

fun View.longErrorSnackbar(
@StringRes text: Int,
@StringRes actionText: Int? = null,
action: (() -> Unit)? = null,
) {
val snackbar = Snackbar
.make(this, text, Snackbar.LENGTH_LONG)

if (action != null && actionText != null) {
snackbar.setAction(actionText) { action.invoke() }
}

snackbar.show()
}

fun View.longErrorSnackbar(
text: String,
duration: Int? = null,
@StringRes actionText: Int? = null,
action: (() -> Unit)? = null,
) {
val snackbar = Snackbar
.make(this, text, Snackbar.LENGTH_LONG)
.setTextColor(WHITE)

if (action != null && actionText != null) {
snackbar.setAction(actionText) { action.invoke() }
}
if (duration != null) {
snackbar.duration = duration
}

snackbar.view.setBackgroundColor(Color(0xFFE0244D).toArgb());
snackbar.show()
}
68 changes: 56 additions & 12 deletions app/src/main/java/org/zotero/android/screens/login/LoginActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,51 @@ package org.zotero.android.screens.login

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.activity.compose.setContent
import android.view.View
import androidx.activity.viewModels
import dagger.hilt.android.AndroidEntryPoint
import org.zotero.android.androidx.content.longErrorSnackbar
import org.zotero.android.androidx.content.showKeyboard
import org.zotero.android.architecture.BaseActivity
import org.zotero.android.architecture.Screen
import org.zotero.android.databinding.LoginActivityBinding
import org.zotero.android.screens.dashboard.DashboardActivity
import org.zotero.android.uicomponents.theme.CustomTheme
import org.zotero.android.uicomponents.Strings
import org.zotero.android.uicomponents.snackbar.SnackbarMessage

@AndroidEntryPoint
internal class LoginActivity : BaseActivity() {
internal class LoginActivity : BaseActivity(), Screen<LoginViewState, LoginViewEffect> {

private lateinit var binding: LoginActivityBinding

private val viewModel: LoginViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContent {
CustomTheme {
LoginScreen(
onBack = { finish() },
navigateToDashboard = {
startActivity(DashboardActivity.getIntentClearTask(this))
}
)
}
binding = LoginActivityBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
viewModel.observeViewChanges(this)

binding.signInButton.setOnClickListener {
viewModel.onUsernameChanged(binding.usernameEditText.text.toString())
viewModel.onPasswordChanged(binding.passwordEditText.text.toString())
viewModel.onSignInClicked()
}
binding.cancelButton.setOnClickListener {
finish()
}
binding.forgotPasswordButton.setOnClickListener {
val intent = Intent(
Intent.ACTION_VIEW,
Uri.parse("https://www.zotero.org/user/lostpassword?app=1")
)
startActivity(intent)
}
showKeyboard(binding.usernameEditText)
}

companion object {
Expand All @@ -35,5 +57,27 @@ internal class LoginActivity : BaseActivity() {
}
}
}

override fun render(state: LoginViewState) {
val snackbarMessage = state.snackbarMessage
if (snackbarMessage != null && snackbarMessage is SnackbarMessage.ErrorMessageString) {
binding.root.longErrorSnackbar(snackbarMessage.message)
viewModel.dismissSnackbar()
}
if (state.isLoading) {
binding.signInButton.text = ""
binding.progressIndicator.visibility = View.VISIBLE
} else {
binding.signInButton.text = getString(Strings.onboarding_sign_in)
binding.progressIndicator.visibility = View.GONE
}
}

override fun trigger(effect: LoginViewEffect) = when (effect) {
LoginViewEffect.NavigateBack -> finish()
LoginViewEffect.NavigateToDashboard -> {
startActivity(DashboardActivity.getIntentClearTask(this))
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ internal class LoginViewModel @Inject constructor(
}
}

private fun dismissSnackbar() {
fun dismissSnackbar() {
updateState { copy(snackbarMessage = null) }
}

Expand Down
6 changes: 6 additions & 0 deletions app/src/main/res/drawable/round_corners_blue_button.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="@color/zoteroDefaultBlue"/>
<corners android:radius="50dp"/>
</shape>
123 changes: 123 additions & 0 deletions app/src/main/res/layout/login_activity.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

<ImageView
android:id="@+id/background_image"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
android:src="@color/surface"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<LinearLayout
android:id="@+id/cancel_button"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:orientation="horizontal"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:gravity="center"
app:layout_constraintWidth_percent="0.9">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cancel"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
style="@style/defaultTextStyle"
android:textColor="@color/zoteroDefaultBlue" />

</LinearLayout>

<LinearLayout
android:id="@+id/user_details_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layout_constraintWidth_max="430dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">

<EditText
android:id="@+id/username_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/login.username"
android:textColorHint="@color/cool_grey"
style="@style/defaultTextStyle"
android:inputType="text"
android:maxLines="1"
app:backgroundTint="#FFEEEFF5"
android:autofillHints="username"
android:paddingBottom="25dp" />

<EditText
android:id="@+id/password_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/login.password"
android:autofillHints="password"
android:textColorHint="@color/cool_grey"
style="@style/defaultTextStyle"
android:inputType="textPassword"
app:backgroundTint="#FFEEEFF5"
android:paddingBottom="25dp"/>

<FrameLayout
android:layout_marginTop="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ProgressBar
android:id="@+id/progress_indicator"
android:layout_width="25dp"
android:layout_height="25dp"
android:visibility="gone"
style="@style/loading_indicator_style"
android:translationZ="5dp"
android:layout_gravity="center"/>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/sign_in_button"
android:layout_width="match_parent"
android:layout_height="48dp"
style="@style/h2"
android:background="@drawable/round_corners_blue_button"
android:text="@string/onboarding.sign_in"
android:textColor="@color/white"
android:textAllCaps="false"
/>



</FrameLayout>

<TextView
android:id="@+id/forgot_password_button"
android:text="@string/login.forgot_password"
android:layout_marginTop="24dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@color/zoteroBlueWithDarkMode"
style="@style/defaultTextStyle"/>

</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
2 changes: 2 additions & 0 deletions app/src/main/res/values-night/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

<color name="ui_divider">#4E4E4E</color>
<color name="primary_text_color">@color/white</color>
<color name="surface">@color/black</color>
<color name="card_background">@color/dark_charcoal</color>
<color name="text_color_on_primary">@color/charcoal</color>
<color name="cardview_background">@color/dark_theme_surface</color>
Expand All @@ -26,5 +27,6 @@
<color name="pdf_annotations_divider_background">#1B1B1C</color>
<color name="pdf_annotations_body_text">#5B5B5E</color>
<color name="pdf_annotations_topbar_background">#282828</color>
<color name="zoteroDefaultBlue">#FF4072E5</color>
<color name="zoteroBlueWithDarkMode">#FF335BB8</color>
</resources>
2 changes: 2 additions & 0 deletions app/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
<color name="rain_grey">#abacb7</color>
<color name="onyx">#32333C</color>
<color name="red">#FF001F</color>
<color name="zoteroDefaultBlue">#FF4072E5</color>
<color name="zoteroBlueWithDarkMode">#FF4071E6</color>
<color name="surface">@color/white</color>

<color name="checkbox_light">@color/cool_grey</color>
<color name="checkbox_dark">@color/white</color>
Expand Down
20 changes: 20 additions & 0 deletions app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,24 @@
<item name="colorControlNormal">#9D9CA2</item>
</style>

<style name="defaultTextStyle">
<item name="android:textSize">15sp</item>
<item name="android:fontFamily">@font/suisse_intl_regular</item>
<item name="android:letterSpacing">0</item>
</style>
<style name="h2">
<item name="android:textSize">17sp</item>
<item name="android:fontFamily">@font/suisse_intl_semibold</item>
<item name="android:letterSpacing">0</item>
</style>

<style name="loading_indicator_style">

<item name="android:layout_width">40dp</item>
<item name="android:layout_height">40dp</item>
<item name="android:indeterminateTint">@color/white</item>
<item name="android:indeterminateTintMode">src_in</item>
<item name="android:indeterminate">true</item>
</style>

</resources>
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/BuildConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ object BuildConfig {
const val compileSdkVersion = 34
const val targetSdk = 33

val versionCode = 38 // Must be updated on every build
val versionCode = 39 // Must be updated on every build
val version = Version(
major = 1,
minor = 0,
Expand Down

0 comments on commit 89d6a13

Please sign in to comment.