refactor(ui): extract shared widgets, drop dead screens

Extract InLibraryBadge (pasted verbatim in five screens) and
playLocalIfAvailable (duplicated in three) into shared code, and delete
SearchScreen, LibraryPlaylistsScreen, and CollapsingHeader, which are
imported nowhere in lib/.
This commit is contained in:
zarzet
2026-07-09 19:02:05 +07:00
parent 46491c137a
commit fd7424dd81
11 changed files with 139 additions and 1325 deletions
+84
View File
@@ -0,0 +1,84 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotiflac_android/l10n/l10n.dart';
import 'package:spotiflac_android/models/track.dart';
import 'package:spotiflac_android/providers/download_queue_provider.dart';
import 'package:spotiflac_android/providers/local_library_provider.dart';
import 'package:spotiflac_android/providers/playback_provider.dart';
import 'package:spotiflac_android/utils/file_access.dart';
/// Plays [track] from download history or the local library when a matching
/// file already exists on disk.
///
/// Returns true when playback started (or when an error was surfaced to the
/// user), so callers can skip enqueueing a download; returns false when no
/// local copy is available. Stale history entries whose file no longer exists
/// are pruned as a side effect.
Future<bool> playLocalIfAvailable(
BuildContext context,
WidgetRef ref,
Track track,
) async {
final historyNotifier = ref.read(downloadHistoryProvider.notifier);
try {
DownloadHistoryItem? historyItem = await historyNotifier.getBySpotifyIdAsync(
track.id,
);
final isrc = track.isrc?.trim();
historyItem ??= (isrc != null && isrc.isNotEmpty)
? await historyNotifier.getByIsrcAsync(isrc)
: null;
historyItem ??= await historyNotifier.findByTrackAndArtistAsync(
track.name,
track.artistName,
);
if (historyItem != null) {
final exists = await fileExists(historyItem.filePath);
if (exists) {
await ref
.read(playbackProvider.notifier)
.playLocalPath(
path: historyItem.filePath,
title: track.name,
artist: track.artistName,
album: track.albumName,
coverUrl: track.coverUrl ?? '',
);
return true;
}
historyNotifier.removeFromHistory(historyItem.id);
}
final localItem = await ref
.read(localLibraryProvider.notifier)
.findExistingAsync(
isrc: isrc,
trackName: track.name,
artistName: track.artistName,
);
if (localItem != null && await fileExists(localItem.filePath)) {
await ref
.read(playbackProvider.notifier)
.playLocalPath(
path: localItem.filePath,
title: localItem.trackName,
artist: localItem.artistName,
album: localItem.albumName,
coverUrl: localItem.coverPath ?? track.coverUrl ?? '',
);
return true;
}
} catch (e) {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(context.l10n.snackbarCannotOpenFile('$e'))),
);
}
return true;
}
return false;
}