Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions lib/ui/screens/browse/favorites_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,14 @@ class _FavoritesScreenState extends State<FavoritesScreen> with GridFocusNodeMix
return _vm.rowItems[types[_selectedTab]] ?? const [];
}

/// The list the grid focus nodes are keyed on.
List<AggregatedItem> get _focusTrackedItems =>
_vm.viewStyle == FavoritesViewStyle.library
? _vm.gridItems
: _currentTabItems();

void _maybeBumpGridVersion() {
final current = _vm.viewStyle == FavoritesViewStyle.library
? _vm.gridItems
: _currentTabItems();
final current = _focusTrackedItems;
final length = current.length;
final firstId = length == 0 ? null : current.first.id;
if (length != _lastGridItemsLength || firstId != _lastGridFirstItemId) {
Expand Down Expand Up @@ -353,7 +357,11 @@ class _FavoritesScreenState extends State<FavoritesScreen> with GridFocusNodeMix
_vm.viewStyle == FavoritesViewStyle.home ? _tabsFocusNode : null,
child: QuickReturnWrapper(
scrollController: _scrollController,
topFocusNode: getGridItemFocusNode(0),
// cleanupGridFocusNodes disposes node 0 once the list empties, and the
// wrapper would keep holding it, so pass nothing instead.
topFocusNode: _focusTrackedItems.isNotEmpty
? getGridItemFocusNode(0)
: null,
child: _buildContent(context),
),
);
Expand Down
10 changes: 8 additions & 2 deletions lib/ui/screens/browse/library_browse_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ class _LibraryBrowseScreenState extends State<LibraryBrowseScreen>
/// Whether the scroll view has settled metrics and is within
/// [_kLoadMoreExtent] of its end.
bool get _nearGridEnd {
if (!_scrollController.hasClients) return false;
// Two grids briefly share the controller while one is swapped out.
if (_scrollController.positions.length != 1) return false;
final pos = _scrollController.position;
Expand Down Expand Up @@ -729,7 +730,9 @@ class _LibraryBrowseScreenState extends State<LibraryBrowseScreen>
_vm.scrollDirection == LibraryScrollDirection.horizontal
? Axis.horizontal
: Axis.vertical,
topFocusNode: getGridItemFocusNode(0),
// cleanupGridFocusNodes disposes node 0 once the list empties, and
// the wrapper would keep holding it, so pass nothing instead.
topFocusNode: _vm.items.isNotEmpty ? getGridItemFocusNode(0) : null,
child: _buildContent(context),
),
);
Expand Down Expand Up @@ -1492,7 +1495,7 @@ class _LibraryBrowseScreenState extends State<LibraryBrowseScreen>

return Listener(
onPointerSignal: (signal) {
if (signal is PointerScrollEvent) {
if (signal is PointerScrollEvent && _scrollController.hasClients) {
final pos = _scrollController.position;
final newOffset =
(_scrollController.offset + signal.scrollDelta.dy)
Expand All @@ -1518,6 +1521,9 @@ class _LibraryBrowseScreenState extends State<LibraryBrowseScreen>
),
delegate: SliverChildBuilderDelegate(
(context, index) {
// No childCount on this delegate, so returning null is
// what tells the sliver where the list ends.
if (index >= _vm.items.length) return null;
final item = _vm.items[index];
return MediaCard(
title: item.name,
Expand Down
Loading