feat(preview): play short track preview snippets in lists

Add a preview player provider and PreviewButton, a previewUrl field on Track (parsed from search and local redownload), preview buttons in search results, and stop the preview on navigation/tab change via per-tab navigator observers. Includes preview play/stop/unavailable localization strings.
This commit is contained in:
zarzet
2026-06-28 06:06:12 +07:00
parent ce813bc216
commit 2ab0350733
24 changed files with 541 additions and 0 deletions
+4
View File
@@ -13,6 +13,7 @@ class Track {
final String? albumId;
final String? coverUrl;
final String? isrc;
final String? previewUrl;
final int duration;
final int? trackNumber;
final int? discNumber;
@@ -38,6 +39,7 @@ class Track {
this.albumId,
this.coverUrl,
this.isrc,
this.previewUrl,
required this.duration,
this.trackNumber,
this.discNumber,
@@ -81,6 +83,8 @@ class Track {
audioModes != null && audioModes!.contains('DOLBY_ATMOS');
bool get hasAudioQuality => audioQuality != null && audioQuality!.isNotEmpty;
bool get hasPreview => previewUrl != null && previewUrl!.isNotEmpty;
}
@JsonSerializable()
+2
View File
@@ -16,6 +16,7 @@ Track _$TrackFromJson(Map<String, dynamic> json) => Track(
albumId: json['albumId'] as String?,
coverUrl: json['coverUrl'] as String?,
isrc: json['isrc'] as String?,
previewUrl: json['previewUrl'] as String?,
duration: (json['duration'] as num).toInt(),
trackNumber: (json['trackNumber'] as num?)?.toInt(),
discNumber: (json['discNumber'] as num?)?.toInt(),
@@ -46,6 +47,7 @@ Map<String, dynamic> _$TrackToJson(Track instance) => <String, dynamic>{
'albumId': instance.albumId,
'coverUrl': instance.coverUrl,
'isrc': instance.isrc,
'previewUrl': instance.previewUrl,
'duration': instance.duration,
'trackNumber': instance.trackNumber,
'discNumber': instance.discNumber,