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; } }