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
+36
View File
@@ -31,6 +31,37 @@ class AudioQualityBadge extends StatelessWidget {
}
}
class ExplicitBadge extends StatelessWidget {
final ColorScheme colorScheme;
const ExplicitBadge({super.key, required this.colorScheme});
@override
Widget build(BuildContext context) {
return Tooltip(
message: 'Explicit',
child: Container(
width: 14,
height: 14,
alignment: Alignment.center,
decoration: BoxDecoration(
color: colorScheme.onSurfaceVariant.withValues(alpha: 0.85),
borderRadius: BorderRadius.circular(3),
),
child: Text(
'E',
style: TextStyle(
fontSize: 9,
fontWeight: FontWeight.w700,
color: colorScheme.surface,
height: 1.0,
),
),
),
);
}
}
class DolbyAtmosBadge extends StatelessWidget {
final ColorScheme colorScheme;
@@ -118,8 +149,13 @@ List<Widget> buildQualityBadges({
required String? audioQuality,
required String? audioModes,
required ColorScheme colorScheme,
bool explicit = false,
}) {
final badges = <Widget>[];
if (explicit) {
badges.add(const SizedBox(width: 6));
badges.add(ExplicitBadge(colorScheme: colorScheme));
}
if (audioQuality != null && audioQuality.isNotEmpty) {
badges.add(const SizedBox(width: 6));
badges.add(