fix: reduce UI padding between media items

close #629
This commit is contained in:
edde746
2026-03-04 18:36:12 +01:00
parent 3b351d7634
commit 5877673755
6 changed files with 18 additions and 14 deletions
+1 -1
View File
@@ -1168,7 +1168,7 @@ class _DiscoverScreenState extends State<DiscoverScreen>
Positioned(
left: 0,
right: 0,
bottom: -32, // Extend 32px past the hero section bounds
bottom: -2, // Minimal overflow to avoid gap without covering hub header
height: 80, // Tall enough to cover any gap
child: IgnorePointer(
child: Builder(
@@ -73,7 +73,7 @@ class AdaptiveMediaGrid<T> extends StatelessWidget {
}
// Extra top padding for focus decoration (scale + border extends beyond item bounds)
static const double _focusDecorationPadding = 8.0;
static const double _focusDecorationPadding = 3.0;
/// Navigate focus to the sidebar
void _navigateToSidebar(BuildContext context) {
@@ -131,7 +131,7 @@ class _LibraryRecommendedTabState extends BaseLibraryTabState<PlexHub, LibraryRe
_ensureHubKeys(items.length);
return ListView.builder(
padding: const EdgeInsets.fromLTRB(0, 8 + _focusDecorationPadding, 0, 8),
padding: const EdgeInsets.fromLTRB(0, _focusDecorationPadding, 0, 8),
// Allow focus decoration to render outside scroll bounds
clipBehavior: Clip.none,
itemCount: items.length,
+1 -1
View File
@@ -79,5 +79,5 @@ class GridLayoutConstants {
static const double mainAxisSpacing = 0;
/// Standard grid padding
static EdgeInsets get gridPadding => const EdgeInsets.only(left: 8, right: 8, bottom: 8);
static EdgeInsets get gridPadding => const EdgeInsets.only(left: 2, right: 2, bottom: 2);
}
+11 -7
View File
@@ -6,6 +6,7 @@ import 'package:plezy/widgets/app_icon.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:provider/provider.dart';
import '../focus/dpad_navigator.dart';
import '../focus/focus_theme.dart';
import '../focus/input_mode_tracker.dart';
import '../focus/key_event_utils.dart';
import '../providers/settings_provider.dart';
@@ -325,13 +326,13 @@ class HubSectionState extends State<HubSection> {
children: [
// Hub header (NOT focusable - titles should not be focusable)
Padding(
padding: const EdgeInsets.fromLTRB(16, 24, 16, 8),
padding: const EdgeInsets.fromLTRB(8, 12, 8, 4),
child: ExcludeFocus(
child: InkWell(
onTap: widget.hub.more ? () => _navigateToHubDetail(context) : null,
borderRadius: BorderRadius.circular(tokens(context).radiusSm),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 6),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
@@ -420,23 +421,26 @@ class HubSectionState extends State<HubSection> {
// Card dimensions based on hub type
const wideCardMultiplier = 1.5;
final cardWidth = useWideLayout ? baseCardWidth * wideCardMultiplier : baseCardWidth;
final posterWidth = cardWidth - 16; // 8px padding on each side
final posterWidth = cardWidth - 6; // 3px padding on each side
final posterHeight = useWideLayout
? posterWidth *
(9 / 16) // 16:9 for wide layout
: posterWidth * 1.5; // 2:3 for poster layout
final containerHeight = posterHeight + 66;
_itemExtent = cardWidth + 4;
final containerHeight = posterHeight + 48;
final focusBorderWidth = FocusTheme.focusBorderWidth;
final focusExtra = focusBorderWidth * 2; // border on both sides
_itemExtent = cardWidth + focusExtra + 4;
return SizedBox(
height: containerHeight,
height: containerHeight + focusExtra + 4, // extra for scale + border top/bottom
child: HorizontalScrollWithArrows(
controller: _scrollController,
builder: (scrollController) => ListView.builder(
controller: scrollController,
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 5),
clipBehavior: Clip.none,
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
itemCount: isKeyboardMode ? _totalItemCount : widget.hub.items.length,
itemBuilder: (context, index) {
final isItemFocused = hasFocus && index == _focusedIndex;
+3 -3
View File
@@ -218,7 +218,7 @@ class MediaCardState extends State<MediaCard> {
Widget _buildGridCard(BuildContext context, String semanticLabel, String? localPosterPath) {
final item = widget.item;
// Compute actual poster dimensions from card dimensions
final posterWidth = widget.width != null ? widget.width! - 16 : null; // 8px padding each side
final posterWidth = widget.width != null ? widget.width! - 6 : null; // 3px padding each side
final posterHeight = widget.height;
return SizedBox(
@@ -232,7 +232,7 @@ class MediaCardState extends State<MediaCard> {
onSecondaryTap: _showContextMenu,
borderRadius: BorderRadius.circular(tokens(context).radiusSm),
child: Padding(
padding: const EdgeInsets.all(8),
padding: const EdgeInsets.all(3),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -278,7 +278,7 @@ class MediaCardState extends State<MediaCard> {
],
),
),
const SizedBox(height: 4),
const SizedBox(height: 2),
// Title (flattened — no inner Column)
Text(
item is PlexPlaylist ? item.title : (item as PlexMetadata).displayTitle,