mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-23 10:00:49 +02:00
perf(ui): retain track history lookup snapshots
Share the retained history lookup snapshot across albums, playlists, artists, home search results, and library folders. Reuse derived lookups until the track list is replaced. Test reuse with 4,000 items and invalidation after replacement, sorting, and filtering.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:spotiflac_android/screens/track_history_snapshot.dart';
|
||||
import 'package:spotiflac_android/widgets/collection_scaffold.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
@@ -78,6 +79,7 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen>
|
||||
with
|
||||
SelectionModeMixin<AlbumScreen>,
|
||||
CollapsingHeaderScrollMixin<AlbumScreen> {
|
||||
final _historySnapshot = TrackHistorySnapshot();
|
||||
List<Track>? _tracks;
|
||||
bool _isLoading = false;
|
||||
String? _error;
|
||||
@@ -543,13 +545,10 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen>
|
||||
ColorScheme colorScheme,
|
||||
List<Track> tracks,
|
||||
) {
|
||||
final historyLookups = tracks
|
||||
.map(historyLookupForTrack)
|
||||
.toList(growable: false);
|
||||
_historySnapshot.update(tracks);
|
||||
final historyLookups = _historySnapshot.lookups;
|
||||
final existingHistoryKeys = ref.watch(
|
||||
downloadHistoryVisibleBatchExistsProvider(
|
||||
HistoryBatchLookupRequest(historyLookups),
|
||||
),
|
||||
downloadHistoryVisibleBatchExistsProvider(_historySnapshot.request),
|
||||
);
|
||||
return SliverPadding(
|
||||
padding: EdgeInsets.symmetric(horizontal: wideListInset(context)),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:spotiflac_android/screens/track_history_snapshot.dart';
|
||||
import 'package:spotiflac_android/widgets/album_detail_header.dart';
|
||||
import 'package:spotiflac_android/theme/cover_palette.dart';
|
||||
import 'package:spotiflac_android/widgets/app_bottom_sheet.dart';
|
||||
@@ -120,6 +121,7 @@ class ArtistScreen extends ConsumerStatefulWidget {
|
||||
class _ArtistScreenState extends ConsumerState<ArtistScreen>
|
||||
with SelectionModeMixin<ArtistScreen> {
|
||||
bool _isLoadingDiscography = false;
|
||||
final _historySnapshot = TrackHistorySnapshot();
|
||||
List<ArtistAlbum>? _albums;
|
||||
List<ArtistAlbum>? _releases;
|
||||
List<Track>? _topTracks;
|
||||
|
||||
@@ -311,13 +311,10 @@ extension _ArtistScreenSections on _ArtistScreenState {
|
||||
}
|
||||
|
||||
final tracks = _topTracks!;
|
||||
final historyLookups = tracks
|
||||
.map(historyLookupForTrack)
|
||||
.toList(growable: false);
|
||||
_historySnapshot.update(tracks);
|
||||
final historyLookups = _historySnapshot.lookups;
|
||||
final existingHistoryKeys = ref.watch(
|
||||
downloadHistoryVisibleBatchExistsProvider(
|
||||
HistoryBatchLookupRequest(historyLookups),
|
||||
),
|
||||
downloadHistoryVisibleBatchExistsProvider(_historySnapshot.request),
|
||||
);
|
||||
const tracksPerPage = 5;
|
||||
final pageCount = (tracks.length / tracksPerPage).ceil();
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:spotiflac_android/screens/track_history_snapshot.dart';
|
||||
import 'package:spotiflac_android/theme/app_tokens.dart';
|
||||
import 'package:spotiflac_android/widgets/app_bottom_sheet.dart';
|
||||
import 'package:spotiflac_android/widgets/app_sliver_header.dart';
|
||||
@@ -60,6 +61,7 @@ class HomeTab extends ConsumerStatefulWidget {
|
||||
|
||||
class _HomeTabState extends ConsumerState<HomeTab>
|
||||
with AutomaticKeepAliveClientMixin, SingleTickerProviderStateMixin {
|
||||
final _historySnapshot = TrackHistorySnapshot();
|
||||
final _urlController = TextEditingController();
|
||||
final FocusNode _searchFocusNode = FocusNode();
|
||||
String? _lastSearchQuery;
|
||||
|
||||
@@ -403,13 +403,10 @@ extension _HomeTabSearchResultsUI on _HomeTabState {
|
||||
}
|
||||
|
||||
if (sortedTracks.isNotEmpty) {
|
||||
final historyLookups = sortedTracks
|
||||
.map(historyLookupForTrack)
|
||||
.toList(growable: false);
|
||||
_historySnapshot.update(sortedTracks);
|
||||
final historyLookups = _historySnapshot.lookups;
|
||||
final existingHistoryKeys = ref.watch(
|
||||
downloadHistoryVisibleBatchExistsProvider(
|
||||
HistoryBatchLookupRequest(historyLookups),
|
||||
),
|
||||
downloadHistoryVisibleBatchExistsProvider(_historySnapshot.request),
|
||||
);
|
||||
slivers.addAll(
|
||||
_buildVirtualizedResultSection(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:spotiflac_android/models/track.dart';
|
||||
import 'package:spotiflac_android/providers/download_history_provider.dart';
|
||||
import 'package:spotiflac_android/screens/track_history_snapshot.dart';
|
||||
import 'package:spotiflac_android/providers/library_collections_provider.dart';
|
||||
import 'package:spotiflac_android/services/history_database.dart';
|
||||
|
||||
@@ -9,17 +9,14 @@ class LibraryTracksFolderData {
|
||||
List<CollectionTrackEntry>? _entries;
|
||||
Set<String> keys = const {};
|
||||
List<Track> tracks = const [];
|
||||
HistoryBatchLookupRequest historyRequest = const HistoryBatchLookupRequest(
|
||||
[],
|
||||
);
|
||||
final _history = TrackHistorySnapshot();
|
||||
HistoryBatchLookupRequest get historyRequest => _history.request;
|
||||
|
||||
void update(List<CollectionTrackEntry> entries) {
|
||||
if (identical(entries, _entries)) return;
|
||||
_entries = entries;
|
||||
keys = Set.unmodifiable(entries.map((entry) => entry.key));
|
||||
tracks = List.unmodifiable(entries.map((entry) => entry.track));
|
||||
historyRequest = HistoryBatchLookupRequest.snapshot(
|
||||
tracks.map(historyLookupForTrack),
|
||||
);
|
||||
_history.update(tracks);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:spotiflac_android/screens/track_history_snapshot.dart';
|
||||
import 'package:spotiflac_android/widgets/album_detail_header.dart';
|
||||
import 'package:spotiflac_android/screens/selection_mode_mixin.dart';
|
||||
import 'package:spotiflac_android/widgets/collection_scaffold.dart';
|
||||
@@ -54,6 +55,7 @@ class _PlaylistScreenState extends ConsumerState<PlaylistScreen>
|
||||
with
|
||||
SelectionModeMixin<PlaylistScreen>,
|
||||
CollapsingHeaderScrollMixin<PlaylistScreen> {
|
||||
final _historySnapshot = TrackHistorySnapshot();
|
||||
List<Track>? _fetchedTracks;
|
||||
bool _isLoading = false;
|
||||
String? _error;
|
||||
@@ -396,13 +398,10 @@ class _PlaylistScreenState extends ConsumerState<PlaylistScreen>
|
||||
);
|
||||
}
|
||||
|
||||
final historyLookups = _tracks
|
||||
.map(historyLookupForTrack)
|
||||
.toList(growable: false);
|
||||
_historySnapshot.update(_tracks);
|
||||
final historyLookups = _historySnapshot.lookups;
|
||||
final existingHistoryKeys = ref.watch(
|
||||
downloadHistoryVisibleBatchExistsProvider(
|
||||
HistoryBatchLookupRequest(historyLookups),
|
||||
),
|
||||
downloadHistoryVisibleBatchExistsProvider(_historySnapshot.request),
|
||||
);
|
||||
return SliverPadding(
|
||||
padding: EdgeInsets.symmetric(horizontal: wideListInset(context)),
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import 'package:spotiflac_android/models/track.dart';
|
||||
import 'package:spotiflac_android/providers/download_history_provider.dart';
|
||||
import 'package:spotiflac_android/services/history_database.dart';
|
||||
|
||||
/// Retains derived lookups while the immutable source list is unchanged.
|
||||
/// Callers replace their list for metadata, order, or filter changes.
|
||||
class TrackHistorySnapshot {
|
||||
List<Track>? _source;
|
||||
HistoryBatchLookupRequest request = HistoryBatchLookupRequest.snapshot([]);
|
||||
|
||||
List<HistoryLookupRequest> get lookups => request.tracks;
|
||||
|
||||
void update(List<Track> tracks) {
|
||||
if (identical(tracks, _source)) return;
|
||||
_source = tracks;
|
||||
request = HistoryBatchLookupRequest.snapshot(
|
||||
tracks.map(historyLookupForTrack),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user