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