195 lines
6.0 KiB
Dart
195 lines
6.0 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||
import 'package:flutter_svg/svg.dart';
|
||
import 'package:go_router/go_router.dart';
|
||
import 'package:maibu_satabot_v2/features/remote_control/presentation/bloc/remote_control_state.dart';
|
||
import 'package:maibu_satabot_v2/features/remote_control/presentation/widgets/status_chip.dart';
|
||
|
||
import '../../../devices/presentation/bloc/devices_cubit.dart';
|
||
import '../bloc/remote_control_cubit.dart';
|
||
|
||
class TopStatusBar extends StatelessWidget {
|
||
const TopStatusBar({super.key});
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
// 监听全局设备状态
|
||
final deviceState = context.watch<DevicesCubit>().state;
|
||
final device = deviceState.selectedDevice;
|
||
|
||
// 监听局部遥控状态
|
||
final remoteState = context.watch<RemoteControlCubit>().state;
|
||
|
||
return Padding(
|
||
padding: const EdgeInsets.all(12.0),
|
||
child: Row(
|
||
children: [
|
||
// 1. 返回按钮 (对应 SimpleSmallFunctionButton)
|
||
_buildIconButton("assets/svgs/remote_back.svg", () => context.pop()),
|
||
const SizedBox(width: 16),
|
||
|
||
// 2. 控制状态 (对应 StatusChipLeft)
|
||
StatusChip(
|
||
text: remoteState.hasPermission ? "正在控制" : "未在控制",
|
||
color: remoteState.hasPermission
|
||
? const Color(0xFF1DB954)
|
||
: Colors.red,
|
||
icon: Icons.eighteen_mp,
|
||
breathing: !remoteState.hasPermission,
|
||
onTap: () {
|
||
if (!remoteState.hasPermission) {
|
||
// 弹出请求权限对话框逻辑
|
||
context.read<RemoteControlCubit>().togglePermissionDialog(true);
|
||
}
|
||
},
|
||
),
|
||
const SizedBox(width: 8),
|
||
|
||
// 3. 锁定状态 (对应 SmallFunctionButton)
|
||
_buildIconButton(
|
||
remoteState.isLocked
|
||
? "assets/svgs/remote_lock.svg"
|
||
: "assets/svgs/remote_lock_open.svg",
|
||
() => context.read<RemoteControlCubit>().toggleLock(),
|
||
isSelected: remoteState.isLocked,
|
||
),
|
||
const SizedBox(width: 8),
|
||
|
||
// 4. 刷新按钮
|
||
_buildIconButton("assets/svgs/remote_refresh.svg", () {}),
|
||
|
||
const Spacer(),
|
||
|
||
// TODO
|
||
_buildControlModeChip(,remoteState.runningStatusModel.controlMode),
|
||
|
||
const SizedBox(width: 8),
|
||
|
||
_buildVoltageChip(remoteState.voltage),
|
||
|
||
const SizedBox(width: 8),
|
||
|
||
// 5. 信号延迟 (对应 pingStatusChip)
|
||
_buildPingChip(remoteState.ping),
|
||
const SizedBox(width: 8),
|
||
|
||
// 6. 电量 (对应 StatusChipRight)
|
||
_buildBatteryChip(remoteState.battery),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildIconButton(
|
||
String svgAsset, // 改为 String 路径,例如 'assets/icons/stop.svg'
|
||
VoidCallback onTap, {
|
||
bool isSelected = false,
|
||
}) {
|
||
return InkWell(
|
||
onTap: onTap,
|
||
borderRadius: BorderRadius.circular(10),
|
||
child: Container(
|
||
width: 32,
|
||
height: 32,
|
||
decoration: BoxDecoration(
|
||
color: isSelected
|
||
? const Color(0xCC0078D4)
|
||
: Colors.grey.withOpacity(0.4),
|
||
borderRadius: BorderRadius.circular(10),
|
||
border: Border.all(color: Colors.white.withOpacity(0.3), width: 0.5),
|
||
),
|
||
padding: const EdgeInsets.all(7),
|
||
child: SvgPicture.asset(
|
||
svgAsset,
|
||
// 这里可以使用 colorFilter 来改变 SVG 的颜色(如果需要根据选中状态变色)
|
||
colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildPingChip(int ping) {
|
||
Color color = ping < 100
|
||
? Colors.green
|
||
: (ping < 200 ? Colors.orange : Colors.red);
|
||
return StatusChip(
|
||
text: "$ping ms",
|
||
color: color.withValues(alpha: 0.6),
|
||
svgColor: color,
|
||
icon: Icons.network_check,
|
||
);
|
||
}
|
||
|
||
Widget _buildControlModeChip(ControlMode mode) {
|
||
String displayText;
|
||
switch (mode) {
|
||
case ControlMode.BLE:
|
||
displayText = '蓝牙模式';
|
||
break;
|
||
case ControlMode.LOCAL:
|
||
displayText = '本地模式';
|
||
break;
|
||
case ControlMode.TCP:
|
||
displayText = 'TCP模式';
|
||
break;
|
||
case ControlMode.NONE:
|
||
displayText = '无模式';
|
||
break;
|
||
case ControlMode.OTHER:
|
||
displayText = '其他模式';
|
||
break;
|
||
default:
|
||
displayText = '未知模式';
|
||
}
|
||
|
||
return StatusChip(
|
||
text: displayText,
|
||
color: Colors.blue.withValues(alpha: 0.6),
|
||
svgColor: Colors.blue,
|
||
svgPath: "assets/svgs/remote_net.svg",
|
||
);
|
||
}
|
||
|
||
Widget _buildVoltageChip(int voltage) {
|
||
return StatusChip(
|
||
text: "$voltage V",
|
||
color: Color(0xFFFACC15).withValues(alpha: 0.6),
|
||
svgColor: Color(0xFFFACC15),
|
||
svgPath: "assets/svgs/remote_zap.svg",
|
||
);
|
||
}
|
||
|
||
Widget _buildBatteryChip(int level) {
|
||
// 1. 根据数值判断图片路径 (逻辑与之前一致)
|
||
String svgPath;
|
||
Color color;
|
||
|
||
if (level >= 90) {
|
||
svgPath = "assets/svgs/remote_battery_full.svg";
|
||
color = Colors.green;
|
||
} else if (level >= 50) {
|
||
svgPath = "assets/svgs/remote_battery_middle.svg";
|
||
color = Colors.greenAccent;
|
||
} else if (level >= 20) {
|
||
svgPath = "assets/svgs/remote_battery_low.svg";
|
||
color = Colors.orange;
|
||
} else if (level >= 10) {
|
||
svgPath = "assets/svgs/remote_battery_warning.svg";
|
||
color = Colors.redAccent;
|
||
} else {
|
||
svgPath = "assets/svgs/remote_battery_none.svg";
|
||
color = Colors.red;
|
||
}
|
||
|
||
// 2. 使用 StatusChip 包装,但 icon 传入 SvgPicture
|
||
return StatusChip(
|
||
text: "$level%",
|
||
color: color.withValues(alpha: 0.6),
|
||
svgColor: color,
|
||
// 如果你的 StatusChip 已经改为接受 Widget,则直接传 SvgPicture
|
||
// 如果 StatusChip 目前只接受 IconData,你需要按我之前的建议给它加个 leading 参数
|
||
svgPath: svgPath,
|
||
);
|
||
}
|
||
}
|