Fix lint issues

This commit is contained in:
Alex Gabor 2022-04-05 09:54:13 +03:00
parent f738a59c23
commit c11d3e96d3
12 changed files with 97 additions and 130 deletions

View file

@ -36,7 +36,6 @@ class AuthComposeInstrumentedTest : KoinTest {
val ruleOrder: RuleChain = RuleChain.outerRule(mockServerScenarioSetupTestRule) val ruleOrder: RuleChain = RuleChain.outerRule(mockServerScenarioSetupTestRule)
.around(dispatcherTestRule) .around(dispatcherTestRule)
@Before @Before
fun setup() { fun setup() {
stateRestorationTester.setContent { stateRestorationTester.setContent {

View file

@ -1,8 +1,14 @@
package org.fnives.test.showcase.ui package org.fnives.test.showcase.ui
import android.content.Context import android.content.Context
import androidx.compose.ui.test.* import androidx.compose.ui.test.assertCountEquals
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertTextContains
import androidx.compose.ui.test.junit4.ComposeTestRule import androidx.compose.ui.test.junit4.ComposeTestRule
import androidx.compose.ui.test.onAllNodesWithTag
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performTextInput
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
import org.fnives.test.showcase.compose.screen.auth.AuthScreenTag import org.fnives.test.showcase.compose.screen.auth.AuthScreenTag
@ -44,5 +50,4 @@ class ComposeLoginRobot(
composeTestRule.onNodeWithTag(AuthScreenTag.LoginError) composeTestRule.onNodeWithTag(AuthScreenTag.LoginError)
.assertTextContains(ApplicationProvider.getApplicationContext<Context>().resources.getString(stringId)) .assertTextContains(ApplicationProvider.getApplicationContext<Context>().resources.getString(stringId))
} }
} }

View file

@ -34,16 +34,19 @@ fun AppNavigation(isUserLogeInUseCase: IsUserLoggedInUseCase = get()) {
) { ) {
composable("Splash") { SplashScreen() } composable("Splash") { SplashScreen() }
composable("Auth") { composable("Auth") {
AuthScreen(modifier = Modifier.testTag(AppNavigationTag.AuthScreen), AuthScreen(
modifier = Modifier.testTag(AppNavigationTag.AuthScreen),
authScreenState = rememberAuthScreenState( authScreenState = rememberAuthScreenState(
onLoginSuccess = { navController.navigate("Home") } onLoginSuccess = { navController.navigate("Home") }
)) )
)
} }
composable("Home") { composable("Home") {
HomeScreen( HomeScreen(
Modifier.testTag(AppNavigationTag.HomeScreen), modifier = Modifier.testTag(AppNavigationTag.HomeScreen),
homeScreenState = rememberHomeScreenState( homeScreenState = rememberHomeScreenState(
onLogout = { navController.navigate("Auth") }) onLogout = { navController.navigate("Auth") }
)
) )
} }
} }

View file

@ -4,11 +4,29 @@ import androidx.compose.animation.graphics.res.animatedVectorResource
import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
import androidx.compose.animation.graphics.vector.AnimatedImageVector import androidx.compose.animation.graphics.vector.AnimatedImageVector
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.* import androidx.compose.material.Button
import androidx.compose.runtime.* import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Snackbar
import androidx.compose.material.SnackbarHost
import androidx.compose.material.SnackbarHostState
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -32,16 +50,23 @@ fun AuthScreen(
ConstraintLayout(modifier.fillMaxSize()) { ConstraintLayout(modifier.fillMaxSize()) {
val (title, credentials, snackbar, loading, login) = createRefs() val (title, credentials, snackbar, loading, login) = createRefs()
Title( Title(
Modifier modifier = Modifier
.statusBarsPadding() .statusBarsPadding()
.constrainAs(title) { top.linkTo(parent.top) }) .constrainAs(title) { top.linkTo(parent.top) }
CredentialsFields(authScreenState, Modifier.constrainAs(credentials) { )
top.linkTo(title.bottom) CredentialsFields(
bottom.linkTo(login.top) authScreenState = authScreenState,
}) modifier = Modifier.constrainAs(credentials) {
Snackbar(authScreenState, Modifier.constrainAs(snackbar) { top.linkTo(title.bottom)
bottom.linkTo(login.top) bottom.linkTo(login.top)
}) }
)
Snackbar(
authScreenState = authScreenState,
modifier = Modifier.constrainAs(snackbar) {
bottom.linkTo(login.top)
}
)
if (authScreenState.loading) { if (authScreenState.loading) {
CircularProgressIndicator( CircularProgressIndicator(
Modifier Modifier
@ -49,7 +74,8 @@ fun AuthScreen(
.constrainAs(loading) { .constrainAs(loading) {
bottom.linkTo(login.top) bottom.linkTo(login.top)
centerHorizontallyTo(parent) centerHorizontallyTo(parent)
}) }
)
} }
LoginButton( LoginButton(
modifier = Modifier modifier = Modifier
@ -84,7 +110,7 @@ private fun PasswordField(authScreenState: AuthScreenState) {
label = { Text(text = stringResource(id = R.string.password)) }, label = { Text(text = stringResource(id = R.string.password)) },
placeholder = { Text(text = stringResource(id = R.string.password)) }, placeholder = { Text(text = stringResource(id = R.string.password)) },
trailingIcon = { trailingIcon = {
val image = AnimatedImageVector.animatedVectorResource(R.drawable.avd_show_password) val image = AnimatedImageVector.animatedVectorResource(R.drawable.show_password)
Icon( Icon(
painter = rememberAnimatedVectorPainter(image, passwordVisible), painter = rememberAnimatedVectorPainter(image, passwordVisible),
contentDescription = null, contentDescription = null,
@ -94,7 +120,11 @@ private fun PasswordField(authScreenState: AuthScreenState) {
) )
}, },
onValueChange = { authScreenState.onPasswordChanged(it) }, onValueChange = { authScreenState.onPasswordChanged(it) },
keyboardOptions = KeyboardOptions(autoCorrect = false, imeAction = ImeAction.Done, keyboardType = KeyboardType.Password), keyboardOptions = KeyboardOptions(
autoCorrect = false,
imeAction = ImeAction.Done,
keyboardType = KeyboardType.Password
),
keyboardActions = KeyboardActions(onDone = { keyboardActions = KeyboardActions(onDone = {
keyboardController?.hide() keyboardController?.hide()
authScreenState.onLogin() authScreenState.onLogin()

View file

@ -1,9 +1,13 @@
package org.fnives.test.showcase.compose.screen.auth package org.fnives.test.showcase.compose.screen.auth
import androidx.compose.runtime.* import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.Saver import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.mapSaver import androidx.compose.runtime.saveable.mapSaver
import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch

View file

@ -2,7 +2,14 @@ package org.fnives.test.showcase.compose.screen.home
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
@ -49,7 +56,8 @@ fun HomeScreen(
state = rememberSwipeRefreshState(isRefreshing = homeScreenState.loading), state = rememberSwipeRefreshState(isRefreshing = homeScreenState.loading),
onRefresh = { onRefresh = {
homeScreenState.onRefresh() homeScreenState.onRefresh()
}) { }
) {
LazyColumn(modifier = Modifier.fillMaxSize()) { LazyColumn(modifier = Modifier.fillMaxSize()) {
items(homeScreenState.content) { item -> items(homeScreenState.content) { item ->
Item( Item(
@ -88,15 +96,15 @@ private fun Item(
Text(text = favouriteContent.content.title) Text(text = favouriteContent.content.title)
Text(text = favouriteContent.content.description) Text(text = favouriteContent.content.description)
} }
val favouriteIcon = if (favouriteContent.isFavourite) R.drawable.favorite_24 else R.drawable.favorite_border_24
Image( Image(
painter = painterResource(id = if (favouriteContent.isFavourite) R.drawable.favorite_24 else R.drawable.favorite_border_24), painter = painterResource(id = favouriteIcon),
contentDescription = null, contentDescription = null,
Modifier.clickable { onFavouriteToggle() } Modifier.clickable { onFavouriteToggle() }
) )
} }
} }
@Composable @Composable
private fun Title(modifier: Modifier = Modifier) { private fun Title(modifier: Modifier = Modifier) {
Text( Text(

View file

@ -19,6 +19,7 @@ import org.fnives.test.showcase.model.content.FavouriteContent
import org.fnives.test.showcase.model.shared.Resource import org.fnives.test.showcase.model.shared.Resource
import org.koin.androidx.compose.get import org.koin.androidx.compose.get
@Suppress("LongParameterList")
@Composable @Composable
fun rememberHomeScreenState( fun rememberHomeScreenState(
stateScope: CoroutineScope = rememberCoroutineScope(), stateScope: CoroutineScope = rememberCoroutineScope(),
@ -42,6 +43,7 @@ fun rememberHomeScreenState(
} }
} }
@Suppress("LongParameterList")
class HomeScreenState( class HomeScreenState(
private val stateScope: CoroutineScope, private val stateScope: CoroutineScope,
private val getAllContentUseCase: GetAllContentUseCase, private val getAllContentUseCase: GetAllContentUseCase,

View file

@ -13,7 +13,6 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import org.fnives.test.showcase.R import org.fnives.test.showcase.R
@Composable @Composable
fun SplashScreen() { fun SplashScreen() {
Box(Modifier.fillMaxSize().background(colorResource(R.color.purple_700)), contentAlignment = Alignment.Center) { Box(Modifier.fillMaxSize().background(colorResource(R.color.purple_700)), contentAlignment = Alignment.Center) {

View file

@ -1,88 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2016 The Android Open Source Project
~
~ 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.
-->
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="NewApi">
<aapt:attr name="android:drawable">
<vector
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp">
<path
android:name="strike_through"
android:pathData="@string/path_password_strike_through"
android:strokeColor="@android:color/white"
android:strokeLineCap="square"
android:strokeWidth="1.8"
android:trimPathEnd="0"/>
<group>
<clip-path
android:name="eye_mask"
android:pathData="@string/path_password_eye_mask_visible"/>
<path
android:fillColor="@android:color/white"
android:name="eye"
android:pathData="@string/path_password_eye"/>
</group>
</vector>
</aapt:attr>
<target android:name="eye_mask">
<aapt:attr name="android:animation">
<objectAnimator
android:duration="@integer/hide_password_duration"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="pathData"
android:valueFrom="@string/path_password_eye_mask_visible"
android:valueTo="@string/path_password_eye_mask_strike_through"
android:valueType="pathType"/>
</aapt:attr>
</target>
<target android:name="strike_through">
<aapt:attr name="android:animation">
<objectAnimator
android:duration="@integer/hide_password_duration"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:propertyName="trimPathEnd"
android:valueFrom="0"
android:valueTo="1"/>
</aapt:attr>
</target>
</animated-vector>

View file

@ -34,18 +34,21 @@
android:pathData="@string/path_password_strike_through" android:pathData="@string/path_password_strike_through"
android:strokeColor="@android:color/white" android:strokeColor="@android:color/white"
android:strokeLineCap="square" android:strokeLineCap="square"
android:strokeWidth="1.8"/> android:strokeWidth="1.8"
tools:ignore="PrivateResource" />
<group> <group>
<clip-path <clip-path
android:name="eye_mask" android:name="eye_mask"
android:pathData="@string/path_password_eye_mask_strike_through"/> android:pathData="@string/path_password_eye_mask_strike_through"
tools:ignore="PrivateResource" />
<path <path
android:fillColor="@android:color/white" android:fillColor="@android:color/white"
android:name="eye" android:name="eye"
android:pathData="@string/path_password_eye"/> android:pathData="@string/path_password_eye"
tools:ignore="PrivateResource" />
</group> </group>
@ -63,7 +66,8 @@
android:propertyName="pathData" android:propertyName="pathData"
android:valueFrom="@string/path_password_eye_mask_strike_through" android:valueFrom="@string/path_password_eye_mask_strike_through"
android:valueTo="@string/path_password_eye_mask_visible" android:valueTo="@string/path_password_eye_mask_visible"
android:valueType="pathType"/> android:valueType="pathType"
tools:ignore="PrivateResource" />
</aapt:attr> </aapt:attr>
@ -78,7 +82,8 @@
android:interpolator="@android:interpolator/fast_out_linear_in" android:interpolator="@android:interpolator/fast_out_linear_in"
android:propertyName="trimPathEnd" android:propertyName="trimPathEnd"
android:valueFrom="1" android:valueFrom="1"
android:valueTo="0"/> android:valueTo="0"
tools:ignore="PrivateResource" />
</aapt:attr> </aapt:attr>