fix: overlay sheet theme and scope on mobile

This commit is contained in:
edde746
2026-02-23 13:00:42 +01:00
parent 4095cc27e1
commit a599920ab4
6 changed files with 89 additions and 96 deletions
+3 -4
View File
@@ -1034,9 +1034,8 @@ class _LibrariesScreenState extends State<LibrariesScreen>
// Compute visible libraries (filtered from all libraries)
final visibleLibraries = allLibraries.where((lib) => !hiddenKeys.contains(lib.globalKey)).toList();
return OverlaySheetHost(
child: Scaffold(
body: ScrollConfiguration(
return Scaffold(
body: ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
child: CustomScrollView(
controller: _outerScrollController,
@@ -1171,12 +1170,12 @@ class _LibrariesScreenState extends State<LibrariesScreen>
],
),
),
),
);
}
}
class _LibraryManagementSheet extends StatefulWidget {
final bool isDialog;
final List<PlexLibrary> allLibraries;
final Set<String> hiddenLibraryKeys;
@@ -822,58 +822,54 @@ class _LibraryBrowseTabState extends BaseLibraryTabState<PlexMetadata, LibraryBr
// For folders mode, use FolderTreeView instead of grid/list
if (_selectedGrouping == 'folders') {
return OverlaySheetHost(
child: Column(
children: [
_buildChipsBar(),
Expanded(
child: FolderTreeView(
libraryKey: widget.library.key,
serverId: widget.library.serverId,
onRefresh: updateItem,
firstItemFocusNode: firstItemFocusNode,
onNavigateUp: () => _groupingChipFocusNode.requestFocus(),
),
return Column(
children: [
_buildChipsBar(),
Expanded(
child: FolderTreeView(
libraryKey: widget.library.key,
serverId: widget.library.serverId,
onRefresh: updateItem,
firstItemFocusNode: firstItemFocusNode,
onNavigateUp: () => _groupingChipFocusNode.requestFocus(),
),
],
),
),
],
);
}
// For list/grid modes, use Stack with chips layered on top of grid.
// This allows the grid to use Clip.none for focus decorations while
// the chips bar (with background) covers any overflow at the top.
return OverlaySheetHost(
child: Stack(
children: [
// Grid fills the entire area, with top padding for chips bar
Positioned.fill(child: _buildScrollableContent()),
// Chips bar on top with solid background
Positioned(top: 0, left: 0, right: 0, child: _buildChipsBar()),
// Alpha jump bar / scroll handle on the right edge
if (_shouldShowAlphaJumpBar)
Positioned(
top: _chipsBarHeight,
right: 0,
bottom: 0,
child: _isPhone(context)
? AlphaScrollHandle(
firstCharacters: _firstCharacters,
onJump: _jumpToIndex,
currentLetter: _currentAlphaLetter,
isScrolling: _isScrollActive,
)
: AlphaJumpBar(
firstCharacters: _firstCharacters,
onJump: _jumpToIndex,
currentLetter: _currentAlphaLetter,
focusNode: _alphaJumpBarFocusNode,
onNavigateLeft: _navigateToGridNearScroll,
onBack: _navigateToGridNearScroll,
),
),
],
),
return Stack(
children: [
// Grid fills the entire area, with top padding for chips bar
Positioned.fill(child: _buildScrollableContent()),
// Chips bar on top with solid background
Positioned(top: 0, left: 0, right: 0, child: _buildChipsBar()),
// Alpha jump bar / scroll handle on the right edge
if (_shouldShowAlphaJumpBar)
Positioned(
top: _chipsBarHeight,
right: 0,
bottom: 0,
child: _isPhone(context)
? AlphaScrollHandle(
firstCharacters: _firstCharacters,
onJump: _jumpToIndex,
currentLetter: _currentAlphaLetter,
isScrolling: _isScrollActive,
)
: AlphaJumpBar(
firstCharacters: _firstCharacters,
onJump: _jumpToIndex,
currentLetter: _currentAlphaLetter,
focusNode: _alphaJumpBarFocusNode,
onNavigateLeft: _navigateToGridNearScroll,
onBack: _navigateToGridNearScroll,
),
),
],
);
}
+6 -3
View File
@@ -17,6 +17,7 @@ import '../utils/platform_detector.dart';
import '../utils/video_player_navigation.dart';
import '../main.dart';
import '../mixins/refreshable.dart';
import '../widgets/overlay_sheet.dart';
import '../mixins/tab_visibility_aware.dart';
import '../navigation/navigation_tabs.dart';
import '../providers/multi_server_provider.dart';
@@ -1054,9 +1055,10 @@ class _MainScreenState extends State<MainScreen> with RouteAware, WindowListener
);
}
return Scaffold(
body: IndexedStack(index: _currentIndex, children: _screens),
bottomNavigationBar: Column(
return OverlaySheetHost(
child: Scaffold(
body: IndexedStack(index: _currentIndex, children: _screens),
bottomNavigationBar: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Reconnect bar when offline
@@ -1102,6 +1104,7 @@ class _MainScreenState extends State<MainScreen> with RouteAware, WindowListener
),
],
),
),
);
}
}
+4 -6
View File
@@ -37,8 +37,6 @@ class _FileInfoBottomSheetState extends State<FileInfoBottomSheet> {
BottomSheetHeader(
title: t.fileInfo.title,
icon: Symbols.info_rounded,
iconColor: Colors.white,
titleColor: Colors.white,
closeFocusNode: _initialFocusNode,
),
// Content
@@ -50,7 +48,7 @@ class _FileInfoBottomSheetState extends State<FileInfoBottomSheet> {
if (widget.title.isNotEmpty) ...[
Text(
widget.title,
style: const TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500),
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
),
const SizedBox(height: 20),
],
@@ -115,7 +113,7 @@ class _FileInfoBottomSheetState extends State<FileInfoBottomSheet> {
Widget _buildSectionHeader(String title) {
return Text(
title,
style: const TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold),
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
);
}
@@ -127,12 +125,12 @@ class _FileInfoBottomSheetState extends State<FileInfoBottomSheet> {
children: [
SizedBox(
width: 140,
child: Text(label, style: TextStyle(color: Colors.grey[400], fontSize: 14)),
child: Text(label, style: TextStyle(color: Theme.of(context).textTheme.bodySmall?.color, fontSize: 14)),
),
Expanded(
child: Text(
value,
style: TextStyle(color: Colors.white, fontSize: 14, fontFamily: isMonospace ? 'monospace' : null),
style: TextStyle(fontSize: 14, fontFamily: isMonospace ? 'monospace' : null),
),
),
],
+31 -33
View File
@@ -1322,41 +1322,39 @@ class _FocusableContextMenuSheetState extends State<_FocusableContextMenuSheet>
@override
Widget build(BuildContext context) {
return SafeArea(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
widget.title,
style: Theme.of(context).textTheme.titleMedium,
maxLines: 1,
overflow: TextOverflow.ellipsis,
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
widget.title,
style: Theme.of(context).textTheme.titleMedium,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
Flexible(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
...widget.actions.asMap().entries.map((entry) {
final index = entry.key;
final action = entry.value;
return FocusableListTile(
focusNode: index == 0 ? _initialFocusNode : null,
leading: AppIcon(action.icon, fill: 1),
title: Text(action.label),
onTap: () => OverlaySheetController.closeAdaptive(context, action.value),
hoverColor: action.hoverColor,
);
}),
],
),
),
Flexible(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
...widget.actions.asMap().entries.map((entry) {
final index = entry.key;
final action = entry.value;
return FocusableListTile(
focusNode: index == 0 ? _initialFocusNode : null,
leading: AppIcon(action.icon, fill: 1),
title: Text(action.label),
onTap: () => OverlaySheetController.closeAdaptive(context, action.value),
hoverColor: action.hoverColor,
);
}),
],
),
),
),
],
),
),
],
);
}
}
+4 -5
View File
@@ -113,7 +113,7 @@ class OverlaySheetController {
context: context,
builder: builder,
constraints: constraints,
backgroundColor: backgroundColor ?? Colors.grey[900],
backgroundColor: backgroundColor ?? Theme.of(context).colorScheme.surface,
barrierColor: Colors.black54,
isScrollControlled: isScrollControlled,
);
@@ -187,7 +187,7 @@ class _OverlaySheetHostState extends State<OverlaySheetHost> with SingleTickerPr
bool _isClosing = false;
bool _barrierDismissible = true;
BoxConstraints? _constraints;
Color _backgroundColor = Colors.grey[900]!;
Color? _explicitBackgroundColor;
// Drag-to-dismiss state
double _dragOffset = 0;
@@ -249,7 +249,7 @@ class _OverlaySheetHostState extends State<OverlaySheetHost> with SingleTickerPr
_isClosing = false;
_barrierDismissible = barrierDismissible;
_constraints = constraints;
if (backgroundColor != null) _backgroundColor = backgroundColor;
_explicitBackgroundColor = backgroundColor;
_dragOffset = 0;
_isDragging = false;
});
@@ -454,7 +454,6 @@ class _OverlaySheetHostState extends State<OverlaySheetHost> with SingleTickerPr
BoxConstraints(
maxWidth: isDesktop ? 700 : double.infinity,
maxHeight: isDesktop ? 400 : size.height * 0.75,
minHeight: isDesktop ? 300 : size.height * 0.5,
);
Widget sheet = FocusScope(
@@ -470,7 +469,7 @@ class _OverlaySheetHostState extends State<OverlaySheetHost> with SingleTickerPr
child: Transform.translate(
offset: Offset(0, _dragOffset.clamp(0, double.infinity)),
child: Material(
color: _backgroundColor,
color: _explicitBackgroundColor ?? Theme.of(context).colorScheme.surface,
borderRadius: const BorderRadius.vertical(top: Radius.circular(16)),
clipBehavior: Clip.antiAlias,
child: SafeArea(