Fix cut off cards on grids with show details enabled (#963)

## Description
Fixes the previous row of cards showing the bottom cut off when the
"Show details" view option is enabled.

### Related issues
Fixes #404
Fixes #877
Related to #882 

### Testing
Emulator

## Screenshots
![grid_show_details
Large](https://github.com/user-attachments/assets/3376275e-261e-4e5a-b874-18be7606a9bf)

## AI or LLM usage
None
This commit is contained in:
Ray 2026-02-23 15:20:25 -05:00 committed by GitHub
parent 3b162a2f98
commit 348a3022d6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 104 additions and 82 deletions

View file

@ -6,7 +6,9 @@ import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.LocalBringIntoViewSpec
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -33,6 +35,7 @@ import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
@ -84,6 +87,7 @@ import com.github.damontecres.wholphin.ui.setValueOnMain
import com.github.damontecres.wholphin.ui.toServerString import com.github.damontecres.wholphin.ui.toServerString
import com.github.damontecres.wholphin.ui.tryRequestFocus import com.github.damontecres.wholphin.ui.tryRequestFocus
import com.github.damontecres.wholphin.ui.util.FilterUtils import com.github.damontecres.wholphin.ui.util.FilterUtils
import com.github.damontecres.wholphin.ui.util.ScrollToTopBringIntoViewSpec
import com.github.damontecres.wholphin.util.ApiRequestPager import com.github.damontecres.wholphin.util.ApiRequestPager
import com.github.damontecres.wholphin.util.DataLoadingState import com.github.damontecres.wholphin.util.DataLoadingState
import com.github.damontecres.wholphin.util.ExceptionHandler import com.github.damontecres.wholphin.util.ExceptionHandler
@ -735,6 +739,7 @@ fun CollectionFolderGrid(
} }
} }
@OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun CollectionFolderGridContent( fun CollectionFolderGridContent(
preferences: UserPreferences, preferences: UserPreferences,
@ -879,14 +884,16 @@ fun CollectionFolderGridContent(
} }
} }
} }
val defaultBringIntoViewSpec = LocalBringIntoViewSpec.current
val density = LocalDensity.current
AnimatedVisibility(viewOptions.showDetails) { AnimatedVisibility(viewOptions.showDetails) {
HomePageHeader( HomePageHeader(
item = focusedItem, item = focusedItem,
modifier = modifier =
Modifier Modifier
.fillMaxWidth() .fillMaxWidth()
.height(140.dp) .height(200.dp)
.padding(16.dp), .padding(top = 48.dp, bottom = 32.dp, start = 8.dp),
) )
} }
when (val state = loadingState) { when (val state = loadingState) {
@ -932,6 +939,15 @@ fun CollectionFolderGridContent(
}, },
columns = viewOptions.columns, columns = viewOptions.columns,
spacing = viewOptions.spacing.dp, spacing = viewOptions.spacing.dp,
bringIntoViewSpec =
remember(viewOptions) {
val spacingPx = with(density) { viewOptions.spacing.dp.toPx() }
if (viewOptions.showDetails) {
ScrollToTopBringIntoViewSpec(spacingPx)
} else {
defaultBringIntoViewSpec
}
},
) )
AnimatedVisibility(showViewOptions) { AnimatedVisibility(showViewOptions) {
ViewOptionsDialog( ViewOptionsDialog(

View file

@ -4,6 +4,8 @@ import androidx.annotation.StringRes
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.focusGroup import androidx.compose.foundation.focusGroup
import androidx.compose.foundation.gestures.BringIntoViewSpec
import androidx.compose.foundation.gestures.LocalBringIntoViewSpec
import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsFocusedAsState import androidx.compose.foundation.interaction.collectIsFocusedAsState
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@ -24,6 +26,7 @@ import androidx.compose.foundation.lazy.layout.LazyLayoutCacheWindow
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
@ -112,6 +115,7 @@ fun <T : CardGridItem> CardGrid(
}, },
columns: Int = 6, columns: Int = 6,
spacing: Dp = 16.dp, spacing: Dp = 16.dp,
bringIntoViewSpec: BringIntoViewSpec = LocalBringIntoViewSpec.current,
) { ) {
val startPosition = initialPosition.coerceIn(0, (pager.size - 1).coerceAtLeast(0)) val startPosition = initialPosition.coerceIn(0, (pager.size - 1).coerceAtLeast(0))
@ -269,6 +273,7 @@ fun <T : CardGridItem> CardGrid(
Box( Box(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
) { ) {
CompositionLocalProvider(LocalBringIntoViewSpec provides bringIntoViewSpec) {
LazyVerticalGrid( LazyVerticalGrid(
columns = GridCells.Fixed(columns), columns = GridCells.Fixed(columns),
horizontalArrangement = Arrangement.spacedBy(spacing), horizontalArrangement = Arrangement.spacedBy(spacing),
@ -366,6 +371,7 @@ fun <T : CardGridItem> CardGrid(
} }
} }
} }
}
val context = LocalContext.current val context = LocalContext.current
val letters = context.getString(R.string.jump_letters) val letters = context.getString(R.string.jump_letters)
// Letters // Letters