feat(metadata): surface explicit content flag with [E] badge

Port of the explicit-content indicator from SpotiFLAC-Web (issue #456):

- Go: add explicit to ExtTrackMetadata (parsed generically from any
  extension via explicit/is_explicit/isExplicit), TrackMetadata, and
  AlbumTrackMetadata; built-in Deezer maps explicit_lyrics and
  explicit_content_lyrics == 1
- Dart: add explicit to the Track model with a tolerant
  parseExplicitFlag helper wired into all backend track parsers
- UI: new ExplicitBadge rendered through buildQualityBadges on album,
  playlist, search, and home track rows
This commit is contained in:
zarzet
2026-07-10 10:12:14 +07:00
parent 8abb9d119b
commit 4c83aeafb5
14 changed files with 137 additions and 11 deletions
+4
View File
@@ -28,6 +28,7 @@ class Track {
final String? itemType;
final String? audioQuality;
final String? audioModes;
final bool? explicit;
const Track({
required this.id,
@@ -54,6 +55,7 @@ class Track {
this.itemType,
this.audioQuality,
this.audioModes,
this.explicit,
});
bool get isSingle {
@@ -82,6 +84,8 @@ class Track {
bool get isDolbyAtmos =>
audioModes != null && audioModes!.contains('DOLBY_ATMOS');
bool get isExplicit => explicit == true;
bool get hasAudioQuality => audioQuality != null && audioQuality!.isNotEmpty;
bool get hasPreview => previewUrl != null && previewUrl!.isNotEmpty;
+2
View File
@@ -35,6 +35,7 @@ Track _$TrackFromJson(Map<String, dynamic> json) => Track(
itemType: json['itemType'] as String?,
audioQuality: json['audioQuality'] as String?,
audioModes: json['audioModes'] as String?,
explicit: json['explicit'] as bool?,
);
Map<String, dynamic> _$TrackToJson(Track instance) => <String, dynamic>{
@@ -62,6 +63,7 @@ Map<String, dynamic> _$TrackToJson(Track instance) => <String, dynamic>{
'itemType': instance.itemType,
'audioQuality': instance.audioQuality,
'audioModes': instance.audioModes,
'explicit': instance.explicit,
};
ServiceAvailability _$ServiceAvailabilityFromJson(Map<String, dynamic> json) =>