91 lines
2.6 KiB
Dart
91 lines
2.6 KiB
Dart
import 'package:flutter/material.dart';
|
||
|
||
import '../models/device.dart';
|
||
import '../services/device_service.dart';
|
||
import '../utils/i10n.dart';
|
||
import 'device_command_sheet.dart';
|
||
import 'status_chip.dart';
|
||
|
||
/// 设备列表项。
|
||
class DeviceListTile extends StatelessWidget {
|
||
const DeviceListTile({
|
||
super.key,
|
||
required this.device,
|
||
this.onTap,
|
||
});
|
||
|
||
/// 设备数据。
|
||
final Device device;
|
||
|
||
/// 点击回调。
|
||
final VoidCallback? onTap;
|
||
|
||
IconData _iconByStatus() {
|
||
switch (device.status) {
|
||
case DeviceStatus.online:
|
||
return Icons.dns;
|
||
case DeviceStatus.offline:
|
||
return Icons.dns_outlined;
|
||
case DeviceStatus.warning:
|
||
return Icons.warning_amber;
|
||
}
|
||
}
|
||
|
||
String _title(BuildContext context) {
|
||
// 设备标识以 MAC 为主(房号独立显示在副标题,不再用「/」粘连)。
|
||
return device.macLabel;
|
||
}
|
||
|
||
String _subtitle(BuildContext context) {
|
||
// 副标题保持「门店 + 型号」不变,并追加独立的「房号:XXX」字段。
|
||
final t = AppLocalizations.of(context);
|
||
final store = device.storeName.isEmpty
|
||
? t.deviceSubtitleStore(t.deviceSubtitleNotSet)
|
||
: t.deviceSubtitleStore(device.storeName);
|
||
final model = '${t.modelLabel}:${device.model.isNotEmpty ? device.model : t.deviceSubtitleNotSet}';
|
||
final room = '${t.roomNo}:${device.roomNo.isNotEmpty ? device.roomNo : t.deviceSubtitleNotSet}';
|
||
return '$store $model $room';
|
||
}
|
||
|
||
void _showCommandSheet(BuildContext context) {
|
||
showModalBottomSheet(
|
||
useSafeArea: true,
|
||
context: context,
|
||
isScrollControlled: true,
|
||
builder: (ctx) => DeviceCommandSheet(
|
||
device: device,
|
||
deviceService: DeviceService(),
|
||
),
|
||
);
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return Card(
|
||
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
|
||
child: ListTile(
|
||
leading: Icon(_iconByStatus(), size: 32),
|
||
title: Text(
|
||
_title(context),
|
||
style: const TextStyle(fontWeight: FontWeight.w600),
|
||
),
|
||
subtitle: Text(_subtitle(context)),
|
||
trailing: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
Builder(
|
||
builder: (context) => IconButton(
|
||
icon: const Icon(Icons.touch_app_outlined),
|
||
tooltip: AppLocalizations.of(context).sendCommand,
|
||
onPressed: () => _showCommandSheet(context),
|
||
),
|
||
),
|
||
StatusChip(status: device.status),
|
||
],
|
||
),
|
||
onTap: onTap,
|
||
),
|
||
);
|
||
}
|
||
}
|