Files
flutterApp/lib/features/remote_control/presentation/widgets/right_joystick_area.dart

126 lines
3.9 KiB
Dart

import 'package:cc_ui_kit/cc_ui_kit.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:vibration/vibration.dart';
import 'package:maibu_satabot_v2/core/localization/app_localizations.dart';
import '../bloc/remote_control_cubit.dart';
class RightJoystickArea extends StatefulWidget {
final bool isLocked;
final double width;
// 修复:删除重复的 key 定义
const RightJoystickArea({
super.key,
required this.isLocked,
required this.width,
});
@override
State<RightJoystickArea> createState() => _RightJoystickAreaState();
}
class _RightJoystickAreaState extends State<RightJoystickArea> {
int _lastX = 0;
bool _hasShownNoPushDialog = false; // 防止重复弹窗
/// 检查是否可以控制,不能则弹出提示
bool _checkCanControl(BuildContext context) {
final cubit = context.read<RemoteControlCubit>();
if (!cubit.isStatusPushActive()) {
if (!_hasShownNoPushDialog) {
_hasShownNoPushDialog = true;
_showNoStatusPushDialog(context);
}
return false;
}
_hasShownNoPushDialog = false;
return true;
}
/// 显示暂未收到推送的提示弹窗(小圆角)
void _showNoStatusPushDialog(BuildContext context) {
showDialog(
context: context,
builder: (ctx) => Dialog(
backgroundColor: Colors.transparent,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
decoration: BoxDecoration(
color: const Color(0xE5333333),
borderRadius: BorderRadius.circular(12),
),
child: const Text(
'暂未收到该机器的推送,不能控制',
style: TextStyle(
color: Colors.white,
fontSize: 14,
),
),
),
),
);
// 1.5秒后自动关闭
Future.delayed(const Duration(milliseconds: 1500), () {
Navigator.of(context).pop();
});
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
IgnorePointer(
ignoring: widget.isLocked,
child: AnimatedOpacity(
duration: const Duration(milliseconds: 300),
opacity: widget.isLocked ? 0.3 : 1.0,
child: CCJoystick(
radius: widget.width,
axisHint: AxisHint.leftRight,
onValueChanged: (value) {
if (!_checkCanControl(context)) return;
int currentX = value.x.toInt();
if (currentX == _lastX) return;
_lastX = currentX;
int finalX = currentX.abs() < 1 ? 0 : currentX;
debugPrint('右摇杆的数据- x: $finalX, y: 0');
context.read<RemoteControlCubit>().updateOriginX(finalX);
},
onPress: () {
if (!_checkCanControl(context)) return;
_triggerVibration();
},
onPanEnd: () async {
_hasShownNoPushDialog = false; // 松手重置,下次触摸重新检查
debugPrint('🕹️ [右摇杆] 松手,强制 X=0, Y=0');
_lastX = 0;
// 🔥 使用安全方法,一次性清零双轴,确保只发送 (X=0, Y=0)
await context.read<RemoteControlCubit>().stopAllMovement();
},
),
),
),
const SizedBox(height: 18),
Text(
AppLocalizations.of(context).translate('remote_control.left_right'),
style: TextStyle(
color: Colors.white.withOpacity(0.5),
fontSize: 12,
fontWeight: FontWeight.w500,
),
),
],
);
}
void _triggerVibration() {
Vibration.hasVibrator().then((has) {
if (has ?? false) Vibration.vibrate(duration: 12);
});
}
}