mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-08-27 21:30:23 +02:00
194 lines
7.0 KiB
Dart
194 lines
7.0 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:spotiflac_android/l10n/l10n.dart';
|
|
import 'package:spotiflac_android/services/batch_metadata_re_enrich.dart';
|
|
import 'package:spotiflac_android/widgets/app_bottom_sheet.dart';
|
|
import 'package:spotiflac_android/widgets/settings_group.dart';
|
|
|
|
Future<bool> showReEnrichReviewSheet(
|
|
BuildContext context, {
|
|
required List<BatchReEnrichPreview> previews,
|
|
}) async {
|
|
final changeCount = previews.fold<int>(
|
|
0,
|
|
(total, preview) => total + preview.changes.length,
|
|
);
|
|
if (changeCount == 0) return false;
|
|
|
|
final confirmed = await showAppBottomSheet<bool>(
|
|
context: context,
|
|
useRootNavigator: true,
|
|
title: context.l10n.trackReEnrichReviewTitle,
|
|
subtitle: context.l10n.trackReEnrichReviewSubtitle(
|
|
changeCount,
|
|
previews.length,
|
|
),
|
|
maxHeightFactor: 0.9,
|
|
builder: (sheetContext) => _ReEnrichReviewContent(previews: previews),
|
|
);
|
|
return confirmed == true;
|
|
}
|
|
|
|
class _ReEnrichReviewContent extends StatelessWidget {
|
|
final List<BatchReEnrichPreview> previews;
|
|
|
|
const _ReEnrichReviewContent({required this.previews});
|
|
|
|
String _fieldLabel(BuildContext context, String field) {
|
|
switch (field) {
|
|
case 'track_name':
|
|
return context.l10n.editMetadataFieldTitle;
|
|
case 'artist_name':
|
|
return context.l10n.editMetadataFieldArtist;
|
|
case 'album_name':
|
|
return context.l10n.editMetadataFieldAlbum;
|
|
case 'album_artist':
|
|
return context.l10n.editMetadataFieldAlbumArtist;
|
|
case 'track_number':
|
|
return context.l10n.editMetadataFieldTrackNum;
|
|
case 'total_tracks':
|
|
return context.l10n.editMetadataFieldTrackTotal;
|
|
case 'disc_number':
|
|
return context.l10n.editMetadataFieldDiscNum;
|
|
case 'total_discs':
|
|
return context.l10n.editMetadataFieldDiscTotal;
|
|
case 'release_date':
|
|
return context.l10n.editMetadataFieldDate;
|
|
case 'isrc':
|
|
return context.l10n.editMetadataFieldIsrc;
|
|
case 'genre':
|
|
return context.l10n.editMetadataFieldGenre;
|
|
case 'composer':
|
|
return context.l10n.editMetadataFieldComposer;
|
|
case 'label':
|
|
return context.l10n.editMetadataFieldLabel;
|
|
case 'copyright':
|
|
return context.l10n.editMetadataFieldCopyright;
|
|
case 'cover_url':
|
|
return context.l10n.editMetadataFieldCover;
|
|
case 'lyrics':
|
|
return context.l10n.trackReEnrichFieldLyrics;
|
|
default:
|
|
return field;
|
|
}
|
|
}
|
|
|
|
String _oldValue(BuildContext context, ReEnrichMetadataChange change) {
|
|
if (change.field == 'cover_url' && change.oldValue.isNotEmpty) {
|
|
return context.l10n.trackCoverCurrent;
|
|
}
|
|
return change.oldValue.isEmpty ? '—' : change.oldValue;
|
|
}
|
|
|
|
String _newValue(BuildContext context, ReEnrichMetadataChange change) {
|
|
if (change.field == 'cover_url') {
|
|
return context.l10n.editMetadataAutoFillCoverAvailable;
|
|
}
|
|
if (change.newValue == '__refresh_online__') {
|
|
return context.l10n.trackReEnrichRefreshOnline;
|
|
}
|
|
return change.newValue;
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final colorScheme = Theme.of(context).colorScheme;
|
|
final visible = previews
|
|
.where((preview) => preview.changes.isNotEmpty)
|
|
.toList(growable: false);
|
|
|
|
return SafeArea(
|
|
top: false,
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Flexible(
|
|
child: ListView.builder(
|
|
shrinkWrap: true,
|
|
padding: const EdgeInsets.only(bottom: 8),
|
|
itemCount: visible.length,
|
|
itemBuilder: (context, index) {
|
|
final preview = visible[index];
|
|
return SettingsGroup(
|
|
children: [
|
|
ListTile(
|
|
leading: const Icon(Icons.audio_file_outlined),
|
|
title: Text(
|
|
preview.item.trackName,
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
subtitle: Text(
|
|
preview.item.artistName,
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
for (final change in preview.changes) ...[
|
|
const Divider(height: 1, indent: 56),
|
|
Semantics(
|
|
label:
|
|
'${_fieldLabel(context, change.field)}: ${_oldValue(context, change)}, ${_newValue(context, change)}',
|
|
child: Padding(
|
|
padding: const EdgeInsets.fromLTRB(56, 10, 16, 10),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
_fieldLabel(context, change.field),
|
|
style: Theme.of(context).textTheme.labelMedium
|
|
?.copyWith(
|
|
color: colorScheme.onSurfaceVariant,
|
|
),
|
|
),
|
|
const SizedBox(height: 3),
|
|
Text.rich(
|
|
TextSpan(
|
|
children: [
|
|
TextSpan(
|
|
text: _oldValue(context, change),
|
|
style: TextStyle(
|
|
color: colorScheme.onSurfaceVariant,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: ' → ',
|
|
style: TextStyle(
|
|
color: colorScheme.primary,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: _newValue(context, change),
|
|
style: const TextStyle(
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
],
|
|
);
|
|
},
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
|
|
child: SizedBox(
|
|
width: double.infinity,
|
|
child: FilledButton.icon(
|
|
onPressed: () => Navigator.pop(context, true),
|
|
icon: const Icon(Icons.save_outlined),
|
|
label: Text(context.l10n.trackReEnrichApplyChanges),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|