Browse Source

Merge commit '0ee1333f733effe72cf19206df355cdccbabb020'

newdev_shunjiawei
lxm 1 year ago
parent
commit
2dfb3773ea
  1. 60
      lib/modules/chat/controllers/chat_controller.dart
  2. 27
      lib/modules/chat/views/chat_view.dart
  3. 144
      lib/modules/chat/views/cloud_background.dart

60
lib/modules/chat/controllers/chat_controller.dart

@ -98,7 +98,9 @@ class ChatController extends GetxController {
String finalResult = '';
// 按住说话防抖
bool isDebounce = false;
Timer? _talkDebounceTimer;
Timer? _talkStartDebounceTimer;
@override
Future<void> onInit() async {
@ -295,6 +297,7 @@ class ChatController extends GetxController {
_autoStopTimer?.cancel();
_scrollDebounceTimer?.cancel(); // 清理防抖计时器
_talkDebounceTimer?.cancel();
_talkStartDebounceTimer?.cancel();
_amapFlutter.dispose();
_locationStream?.cancel();
@ -618,38 +621,46 @@ class ChatController extends GetxController {
// 按下开始说话
void talkLongPress() async {
_talkStartDebounceTimer?.cancel();
_talkDebounceTimer?.cancel();
if (isHoldSpeak.value) return;
isHoldSpeak.value = true;
Haptics.vibrate(HapticsType.success);
_voiceInteractionService.pauseVoiceInteraction();
// 中断当前响应
_interruptCurrentResponse("发送新消息,中断当前响应");
try {
final recognitionStream = await _asrService.startContinuousRecognition();
await Future.delayed(const Duration(milliseconds: 150));
_talkStartDebounceTimer =
Timer(const Duration(milliseconds: 260), () async {
if (isDebounce) return;
isHoldSpeak.value = true;
recognizedText.value = '';
finalResult = '';
Haptics.vibrate(HapticsType.success);
_voiceInteractionService.pauseVoiceInteraction();
// 中断当前响应
_interruptCurrentResponse("发送新消息,中断当前响应");
try {
final recognitionStream =
await _asrService.startContinuousRecognition();
await Future.delayed(const Duration(milliseconds: 260));
isDebounce = true;
recognizedText.value = '';
finalResult = '';
// 监听识别事件
_recognitionSubscription = recognitionStream.listen(
_handleRecognitionEvent,
onError: _handleRecognitionError,
);
} catch (e) {
Logger.error('启动语音识别失败', e);
isHoldSpeak.value = false;
}
// 监听识别事件
_recognitionSubscription = recognitionStream.listen(
_handleRecognitionEvent,
onError: _handleRecognitionError,
);
} catch (e) {
Logger.error('启动语音识别失败', e);
isHoldSpeak.value = false;
}
});
}
// 松开停止说话
void talkLongPressUp() async {
_talkStartDebounceTimer?.cancel();
_talkDebounceTimer?.cancel();
_talkDebounceTimer = Timer(const Duration(milliseconds: 200), () async {
if (!isHoldSpeak.value) return;
isHoldSpeak.value = false;
_talkDebounceTimer = Timer(const Duration(milliseconds: 300), () async {
if (!isDebounce) return;
try {
await _asrService.stopContinuousRecognition();
_recognitionSubscription?.cancel();
@ -668,7 +679,8 @@ class ChatController extends GetxController {
recognizedText.value = '';
finalResult = '';
isHoldSpeak.value = false;
isDebounce = false;
} catch (e) {
Logger.error('停止语音识别失败', e);
}

27
lib/modules/chat/views/chat_view.dart

@ -8,6 +8,7 @@ import '../../../core/theme/app_colors.dart';
import 'animated_gradient_background.dart';
import 'chat_music_card.dart';
import 'chat_navigation_card.dart';
import 'cloud_background.dart';
import 'weather_day_card.dart';
class ChatView extends GetView<ChatController> {
@ -440,7 +441,7 @@ class ChatView extends GetView<ChatController> {
filled: false,
border: InputBorder.none,
focusedBorder: InputBorder.none,
contentPadding: EdgeInsets.only(left: 10.w),
contentPadding: EdgeInsets.only(left: 6.w),
),
onSubmitted: (value) {
if (value.trim().isNotEmpty) {
@ -552,13 +553,23 @@ class ChatView extends GetView<ChatController> {
children: [],
),
Expanded(
child: Container(
width: 200.w,
height: 200.w,
decoration: BoxDecoration(
color:
isDarkMode ? Colors.white.withOpacity(0.1) : Colors.white,
shape: BoxShape.circle,
child: Center(
child: Container(
width: 200.w,
height: 200.w,
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.blue.withOpacity(0.4),
Colors.purple.withOpacity(0.4)
],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
shape: BoxShape.circle,
),
child: CircularFlowAnimation(),
),
),
),

144
lib/modules/chat/views/cloud_background.dart

@ -0,0 +1,144 @@
import 'dart:math';
import 'package:flutter/material.dart';
class CircularFlowAnimation extends StatefulWidget {
const CircularFlowAnimation({super.key});
@override
State<CircularFlowAnimation> createState() => _CircularFlowAnimationState();
}
class _CircularFlowAnimationState extends State<CircularFlowAnimation>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 20),
)..repeat();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: CircularFlowPainter(_controller),
size: Size.infinite,
);
}
}
class CircularFlowPainter extends CustomPainter {
final Animation<double> animation;
CircularFlowPainter(this.animation) : super(repaint: animation);
@override
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2, size.height / 2);
const baseRadius = 150.0;
final time = animation.value * 2 * pi;
// 绘制圆形路径
_drawCircularPath(canvas, center, baseRadius);
// 绘制三个围绕圆形运动的渐变云朵
_drawOrbitingCloud(
canvas: canvas,
center: center,
time: time,
colors: [Colors.blue, Colors.purple],
orbitRadius: baseRadius,
speed: 0.5,
direction: 1,
);
_drawOrbitingCloud(
canvas: canvas,
center: center,
time: time,
colors: [Colors.pink, Colors.orange],
orbitRadius: baseRadius * 0.8,
speed: 1.0,
direction: -1,
);
_drawOrbitingCloud(
canvas: canvas,
center: center,
time: time,
colors: [Colors.green, Colors.yellow],
orbitRadius: baseRadius * 1.2,
speed: 0.3,
direction: 1,
);
_drawOrbitingCloud(
canvas: canvas,
center: center,
time: time,
colors: [Colors.red, Colors.deepOrangeAccent],
orbitRadius: baseRadius * 0.5,
speed: 0.8,
direction: -1,
);
}
void _drawCircularPath(Canvas canvas, Offset center, double radius) {
final paint = Paint()
..color = Colors.red
..style = PaintingStyle.stroke
..strokeWidth = 2
..maskFilter = MaskFilter.blur(BlurStyle.normal, 4);
canvas.drawCircle(center, radius, paint);
}
void _drawOrbitingCloud({
required Canvas canvas,
required Offset center,
required double time,
required List<Color> colors,
required double orbitRadius,
required double speed,
required int direction,
}) {
final angle = time * speed * direction;
final position = Offset(
center.dx + orbitRadius * cos(angle),
center.dy + orbitRadius * sin(angle),
);
final gradient = RadialGradient(
colors: colors,
stops: const [0.3, 1.0],
radius: 0.6,
focal: Alignment(
0.1 + cos(angle * 2) * 0.3,
0.1 + sin(angle * 2) * 0.3,
),
);
final paint = Paint()
..shader = gradient.createShader(Rect.fromCircle(
center: position,
radius: 100 + 30 * sin(time * 3),
))
..maskFilter = MaskFilter.blur(BlurStyle.normal, 40)
..blendMode = BlendMode.plus;
canvas.drawCircle(position, 80 + 20 * cos(time * 2), paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
Loading…
Cancel
Save