mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-08-26 21:02:28 +02:00
142 lines
4.5 KiB
Dart
142 lines
4.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:spotiflac_android/utils/retail_barcode.dart';
|
|
|
|
class MetadataBarcode extends StatelessWidget {
|
|
final String value;
|
|
final String label;
|
|
final VoidCallback? onCopy;
|
|
|
|
const MetadataBarcode({
|
|
super.key,
|
|
required this.value,
|
|
required this.label,
|
|
this.onCopy,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final barcode = encodeRetailBarcode(value);
|
|
if (barcode == null) return const SizedBox.shrink();
|
|
|
|
final colorScheme = Theme.of(context).colorScheme;
|
|
return Semantics(
|
|
label: '$label ${barcode.value}',
|
|
button: onCopy != null,
|
|
child: Material(
|
|
color: colorScheme.surfaceContainerHighest,
|
|
borderRadius: BorderRadius.circular(16),
|
|
clipBehavior: Clip.antiAlias,
|
|
child: InkWell(
|
|
onTap: onCopy,
|
|
child: Padding(
|
|
padding: const EdgeInsets.fromLTRB(14, 12, 14, 14),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Icon(
|
|
Icons.qr_code_2_rounded,
|
|
size: 18,
|
|
color: colorScheme.primary,
|
|
),
|
|
const SizedBox(width: 8),
|
|
Expanded(
|
|
child: Text(
|
|
label,
|
|
style: Theme.of(context).textTheme.labelLarge?.copyWith(
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
),
|
|
Text(
|
|
barcode.symbology,
|
|
style: Theme.of(context).textTheme.labelSmall?.copyWith(
|
|
color: colorScheme.onSurfaceVariant,
|
|
),
|
|
),
|
|
if (onCopy != null) ...[
|
|
const SizedBox(width: 8),
|
|
Icon(
|
|
Icons.copy_rounded,
|
|
size: 16,
|
|
color: colorScheme.onSurfaceVariant,
|
|
),
|
|
],
|
|
],
|
|
),
|
|
const SizedBox(height: 10),
|
|
Container(
|
|
width: double.infinity,
|
|
padding: const EdgeInsets.fromLTRB(10, 12, 10, 9),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(12),
|
|
),
|
|
child: Column(
|
|
children: [
|
|
RepaintBoundary(
|
|
child: SizedBox(
|
|
width: double.infinity,
|
|
height: 76,
|
|
child: CustomPaint(painter: _BarcodePainter(barcode)),
|
|
),
|
|
),
|
|
const SizedBox(height: 7),
|
|
Text(
|
|
barcode.value,
|
|
maxLines: 1,
|
|
overflow: TextOverflow.fade,
|
|
softWrap: false,
|
|
style: const TextStyle(
|
|
color: Colors.black,
|
|
fontFamily: 'monospace',
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w600,
|
|
letterSpacing: 2.2,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _BarcodePainter extends CustomPainter {
|
|
final RetailBarcodeData barcode;
|
|
|
|
const _BarcodePainter(this.barcode);
|
|
|
|
@override
|
|
void paint(Canvas canvas, Size size) {
|
|
final totalModules =
|
|
barcode.modules.length + (barcode.quietZoneModules * 2);
|
|
final moduleWidth = size.width / totalModules;
|
|
final paint = Paint()
|
|
..color = Colors.black
|
|
..style = PaintingStyle.fill
|
|
..isAntiAlias = false;
|
|
|
|
for (var i = 0; i < barcode.modules.length; i++) {
|
|
if (barcode.modules.codeUnitAt(i) != 49) continue;
|
|
final left = (barcode.quietZoneModules + i) * moduleWidth;
|
|
canvas.drawRect(
|
|
Rect.fromLTWH(left, 0, moduleWidth + 0.01, size.height),
|
|
paint,
|
|
);
|
|
}
|
|
}
|
|
|
|
@override
|
|
bool shouldRepaint(covariant _BarcodePainter oldDelegate) {
|
|
return barcode.modules != oldDelegate.barcode.modules ||
|
|
barcode.quietZoneModules != oldDelegate.barcode.quietZoneModules;
|
|
}
|
|
}
|