Files
TimbanganSiab/lib/widgets/data_packet_card.dart
2026-01-29 16:17:31 +07:00

127 lines
4.0 KiB
Dart

import 'package:flutter/material.dart';
import '../services/ble_service.dart';
class DataPacketCard extends StatelessWidget {
final DataPacket packet;
const DataPacketCard({super.key, required this.packet});
@override
Widget build(BuildContext context) {
final timeStr = '${packet.timestamp.hour.toString().padLeft(2, '0')}:'
'${packet.timestamp.minute.toString().padLeft(2, '0')}:'
'${packet.timestamp.second.toString().padLeft(2, '0')}';
return Card(
margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: ExpansionTile(
leading: CircleAvatar(
backgroundColor: Theme.of(context).primaryColor,
child: Text(
'#${packet.packetNumber}',
style: const TextStyle(color: Colors.white, fontSize: 12),
),
),
title: Text(
packet.hexString,
style: const TextStyle(fontFamily: 'monospace', fontSize: 14),
),
subtitle: Text('$timeStr${packet.data.length} bytes'),
children: [
Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildSection('Hex', packet.hexString),
const SizedBox(height: 8),
// 'timbang' style: bytes shown in decimal (matching Python output)
_buildSection('timbang', packet.bytesString),
const SizedBox(height: 16),
if (packet.value32BitUnsigned != null) ...[
_buildValueRow(
'32-bit Unsigned (BE)',
packet.value32BitUnsigned.toString(),
),
_buildValueRow(
'32-bit Signed (BE)',
packet.value32BitSigned.toString(),
),
if (packet.value32BitUnsigned! > 0) ...[
_buildValueRow(
'As Float (÷100)',
(packet.value32BitUnsigned! / 100.0).toStringAsFixed(2),
),
_buildValueRow(
'As Float (÷1000)',
(packet.value32BitUnsigned! / 1000.0).toStringAsFixed(3),
),
],
],
if (packet.value16BitUnsigned != null) ...[
const SizedBox(height: 8),
_buildValueRow(
'16-bit Unsigned (BE)',
packet.value16BitUnsigned.toString(),
),
_buildValueRow(
'16-bit Signed (BE)',
packet.value16BitSigned.toString(),
),
],
if (packet.asciiString != null) ...[
const SizedBox(height: 8),
_buildSection('ASCII', packet.asciiString!),
],
],
),
),
],
),
);
}
Widget _buildSection(String label, String value) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
label,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 12,
color: Colors.grey,
),
),
const SizedBox(height: 4),
SelectableText(
value,
style: const TextStyle(fontFamily: 'monospace', fontSize: 14),
),
],
);
}
Widget _buildValueRow(String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 2),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
label,
style: const TextStyle(fontSize: 12, color: Colors.grey),
),
Text(
value,
style: const TextStyle(
fontFamily: 'monospace',
fontWeight: FontWeight.bold,
),
),
],
),
);
}
}