Skip to content

Commit

Permalink
Improve button and remove focus when scrolling (#319)
Browse files Browse the repository at this point in the history
* Improve button and remove focus when scrolling

* Scroll to start of folder preview when monster size changes
  • Loading branch information
alexandregpereira authored Aug 16, 2024
1 parent c7cebe3 commit 71d4ecf
Show file tree
Hide file tree
Showing 21 changed files with 157 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ internal fun AppBottomNavigation(
val paddingBottom = contentPadding.calculateBottomPadding()
BottomNavigation(
backgroundColor = MaterialTheme.colors.surface,
contentColor = MaterialTheme.colors.onSurface,
elevation = 0.dp,
modifier = Modifier.height(BottomNavigationHeight + paddingBottom)
.padding(bottom = paddingBottom)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import br.alexandregpereira.hunter.ui.compose.AppButton
import br.alexandregpereira.hunter.ui.compose.AppCard
import br.alexandregpereira.hunter.ui.compose.BottomSheet
import br.alexandregpereira.hunter.ui.compose.ScreenHeader
import br.alexandregpereira.hunter.ui.theme.HunterTheme
Expand All @@ -50,7 +50,7 @@ internal fun ItemSelection(
closeClickingOutside = false,
onClose = onClose,
) {
Card(
AppCard(
shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp),
modifier = modifier
.fillMaxWidth()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import br.alexandregpereira.hunter.folder.preview.ui.FolderPreviewScreen
import org.koin.compose.koinInject
Expand All @@ -34,6 +35,7 @@ fun FolderPreviewFeature(

FolderPreviewScreen(
state = state,
actionHandler = remember(stateHolder) { stateHolder },
contentPadding = contentPadding,
onClick = stateHolder::onItemClick,
onLongClick = stateHolder::onItemLongClick,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
Expand All @@ -43,6 +45,7 @@ fun FolderPreview(
monsters: List<MonsterFolderPreview>,
saveButtonText: String,
modifier: Modifier = Modifier,
lazyListState: LazyListState = rememberLazyListState(),
contentPadding: PaddingValues = PaddingValues(),
onClick: (index: String) -> Unit = {},
onLongClick: (index: String) -> Unit = {},
Expand All @@ -53,6 +56,7 @@ fun FolderPreview(
Row {
LazyRow(
modifier = Modifier.fillMaxWidth(0.7f),
state = lazyListState,
horizontalArrangement = Arrangement.spacedBy(16.dp),
contentPadding = PaddingValues(horizontal = 16.dp)
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,19 @@ import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier
import br.alexandregpereira.hunter.folder.preview.FolderPreviewAction
import br.alexandregpereira.hunter.folder.preview.FolderPreviewState
import br.alexandregpereira.hunter.state.ActionHandler
import kotlinx.coroutines.flow.collectLatest

@Composable
internal fun FolderPreviewScreen(
state: FolderPreviewState,
actionHandler: ActionHandler<FolderPreviewAction>,
contentPadding: PaddingValues = PaddingValues(),
modifier: Modifier = Modifier,
onClick: (index: String) -> Unit = {},
Expand All @@ -43,8 +49,21 @@ internal fun FolderPreviewScreen(
exit = fadeOut(animationSpec = spring()),
modifier = modifier
) {
val lazyListState = rememberLazyListState()

LaunchedEffect(lazyListState, actionHandler) {
actionHandler.action.collectLatest { event ->
when (event) {
is FolderPreviewAction.ScrollToStart -> {
lazyListState.animateScrollToItem(0)
}
}
}
}

FolderPreview(
monsters = state.monsters,
lazyListState = lazyListState,
saveButtonText = state.strings.save,
contentPadding = contentPadding,
onClick = onClick,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package br.alexandregpereira.hunter.folder.preview

sealed class FolderPreviewAction {
data object ScrollToStart : FolderPreviewAction()
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ import br.alexandregpereira.hunter.localization.AppLocalization
import br.alexandregpereira.hunter.monster.event.MonsterEvent.OnVisibilityChanges.Show
import br.alexandregpereira.hunter.monster.event.MonsterEventDispatcher
import br.alexandregpereira.hunter.monster.event.collectOnMonsterCompendiumChanges
import br.alexandregpereira.hunter.state.MutableActionHandler
import br.alexandregpereira.hunter.state.UiModel
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
Expand All @@ -49,7 +51,8 @@ class FolderPreviewStateHolder internal constructor(
private val dispatcher: CoroutineDispatcher,
private val analytics: FolderPreviewAnalytics,
private val appLocalization: AppLocalization,
) : UiModel<FolderPreviewState>(FolderPreviewState()) {
) : UiModel<FolderPreviewState>(FolderPreviewState()),
MutableActionHandler<FolderPreviewAction> by MutableActionHandler() {

init {
observeEvents()
Expand Down Expand Up @@ -113,7 +116,12 @@ class FolderPreviewStateHolder internal constructor(
addMonsterToFolderPreview(index)
.flowOn(dispatcher)
.onEach { monsters ->
val previousMonsterListSize = state.value.monsters.size
setState { changeMonsters(monsters) }
if (monsters.size > previousMonsterListSize) {
delay(300)
sendAction(FolderPreviewAction.ScrollToStart)
}
}
.launchIn(scope)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material.Card
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
Expand All @@ -24,6 +22,8 @@ import br.alexandregpereira.hunter.monster.content.MonsterContentManagerEmptyStr
import br.alexandregpereira.hunter.monster.content.MonsterContentManagerStrings
import br.alexandregpereira.hunter.ui.compose.AppButton
import br.alexandregpereira.hunter.ui.compose.AppButtonSize
import br.alexandregpereira.hunter.ui.compose.AppCard
import br.alexandregpereira.hunter.ui.compose.AppSurface
import br.alexandregpereira.hunter.ui.compose.CoilImage
import br.alexandregpereira.hunter.ui.compose.SectionTitle
import br.alexandregpereira.hunter.ui.compose.cardShape
Expand All @@ -44,7 +44,7 @@ internal fun MonsterContentCard(
onAddClick: () -> Unit = {},
onRemoveClick: () -> Unit = {},
onPreviewClick: () -> Unit = {},
) = Card(modifier = modifier, shape = cardShape) {
) = AppCard(modifier = modifier, shape = cardShape) {
Column(Modifier.padding(16.dp)) {
Title(
name = name,
Expand Down Expand Up @@ -189,7 +189,7 @@ private fun Buttons(
@Preview
@Composable
private fun MonsterContentCardPreview() = HunterTheme {
Surface {
AppSurface {
MonsterContentCard(
name = "Name",
originalName = "Other name",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,21 @@ package br.alexandregpereira.hunter.detail.ui
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.material.LocalContentAlpha
import androidx.compose.material.LocalContentColor
import androidx.compose.material.Surface
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import br.alexandregpereira.hunter.detail.ui.resources.Res
import br.alexandregpereira.hunter.detail.ui.resources.ic_shield
import br.alexandregpereira.hunter.ui.compose.AppSurface
import br.alexandregpereira.hunter.ui.theme.HunterTheme
import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.ui.tooling.preview.Preview
import br.alexandregpereira.hunter.ui.compose.IconInfo as IconInfoUi

@Composable
Expand Down Expand Up @@ -61,7 +61,7 @@ internal fun IconInfo(
@Composable
private fun IconInfoArmorClassPreview() {
HunterTheme {
Surface {
AppSurface {
IconInfo(
title = "Armor Class",
painter = painterResource(Res.drawable.ic_shield),
Expand All @@ -77,7 +77,7 @@ private fun IconInfoArmorClassPreview() {
@Composable
private fun IconInfoHitPointPreview() {
HunterTheme {
Surface {
AppSurface {
IconInfo(
title = "28d20 + 252",
painter = rememberVectorPainter(image = Icons.Filled.Favorite),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.KeyboardArrowUp
import androidx.compose.runtime.Composable
Expand Down Expand Up @@ -70,6 +69,7 @@ import br.alexandregpereira.hunter.monster.detail.MonsterState
import br.alexandregpereira.hunter.monster.detail.SpeedState
import br.alexandregpereira.hunter.monster.detail.StatsState
import br.alexandregpereira.hunter.ui.compose.AppBarIcon
import br.alexandregpereira.hunter.ui.compose.AppSurface
import br.alexandregpereira.hunter.ui.compose.BoxCloseButton
import br.alexandregpereira.hunter.ui.compose.ChallengeRatingCircle
import br.alexandregpereira.hunter.ui.compose.LocalScreenSize
Expand Down Expand Up @@ -99,7 +99,7 @@ internal fun MonsterDetailScreen(
onSpellClicked: (String) -> Unit = {},
onLoreClicked: (String) -> Unit = {},
onClose: () -> Unit = {},
) = Surface(color = Color.Transparent) {
) = AppSurface(color = Color.Transparent) {
HorizontalPagerTransitionController(pagerState)

MonsterImageCompose(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import br.alexandregpereira.hunter.monster.registration.MonsterRegistrationInten
import br.alexandregpereira.hunter.monster.registration.MonsterRegistrationState
import br.alexandregpereira.hunter.state.ActionHandler
import br.alexandregpereira.hunter.ui.compose.AppScreen
import br.alexandregpereira.hunter.ui.compose.ClearFocusWhenScrolling
import br.alexandregpereira.hunter.ui.compose.LocalScreenSize
import br.alexandregpereira.hunter.ui.compose.isLandscape
import br.alexandregpereira.hunter.ui.compose.maxBottomSheetWidth
Expand Down Expand Up @@ -53,6 +54,8 @@ internal fun MonsterRegistrationScreen(
}
}

ClearFocusWhenScrolling(lazyListState)

MonsterRegistrationForm(
monster = state.monster,
lazyListState = lazyListState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.dp
import br.alexandregpereira.hunter.ui.compose.ClearFocusWhenScrolling
import kotlin.math.absoluteValue

@Composable
Expand All @@ -52,6 +53,8 @@ internal fun SearchScreen(
val listState = rememberLazyGridState()
val focusManager = LocalFocusManager.current

ClearFocusWhenScrolling(listState)

SearchGrid(
monsterRows = state.monsterRows,
totalResults = state.searchResults,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import androidx.compose.foundation.lazy.grid.LazyGridItemScope
import androidx.compose.foundation.lazy.grid.LazyGridState
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.material.Card
import androidx.compose.material.MaterialTheme.colors
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
Expand All @@ -36,6 +35,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import br.alexandregpereira.hunter.ui.compose.AppCard
import br.alexandregpereira.hunter.ui.compose.SectionTitle
import br.alexandregpereira.hunter.ui.compose.imageCardElevation
import br.alexandregpereira.hunter.ui.compose.imageCardShape
Expand Down Expand Up @@ -95,7 +95,7 @@ fun Compendium(
}
val titleModifier = Modifier.monsterAspectRatio().takeIf { isTileCard }
?: Modifier
Card(
AppCard(
shape = imageCardShape,
elevation = imageCardElevation.takeIf { isTileCard } ?: 0.dp,
backgroundColor = colors.surface.takeIf { isTileCard }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,21 @@

package br.alexandregpereira.hunter.ui.compose

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
Expand All @@ -40,21 +44,21 @@ fun AppButton(
enabled: Boolean = true,
onClick: () -> Unit = {}
) {
Button(
enabled = enabled,
shape = RoundedCornerShape(24.dp),
colors = ButtonDefaults.buttonColors(
backgroundColor = MaterialTheme.colors.surface,
),
elevation = ButtonDefaults.elevation(
defaultElevation = 8.dp,
pressedElevation = 2.dp,
),
val backgroundColorAlpha by animateFloatAsState(
targetValue = if (enabled) 1f else 0.5f
)

Box(
modifier = modifier
.height(size.height.dp)
.fillMaxWidth()
.animatePressed(),
onClick = onClick
.animatePressed(
enabled = enabled,
onClick = onClick
)
.clip(RoundedCornerShape(24.dp))
.background(color = MaterialTheme.colors.primary.copy(alpha = backgroundColorAlpha)),
contentAlignment = Alignment.Center
) {
val fontSizes = when (size) {
AppButtonSize.VERY_SMALL -> 12.sp
Expand All @@ -64,7 +68,9 @@ fun AppButton(
Text(
text = text,
fontWeight = FontWeight.Normal,
color = MaterialTheme.colors.onPrimary.copy(alpha = backgroundColorAlpha),
fontSize = fontSizes,
modifier = Modifier.padding(horizontal = 16.dp)
)
}
}
Expand Down
Loading

0 comments on commit 71d4ecf

Please sign in to comment.