Commit 22908b56 authored by skeyboy's avatar skeyboy

语音播放动画控制

parent 405ae83f
library dash_chat_2;
import 'dart:io';
import 'dart:math';
import 'package:custom_pop_up_menu/custom_pop_up_menu.dart';
import 'package:clipboard/clipboard.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_tts/flutter_tts.dart';
import 'package:flutter_vibrate/flutter_vibrate.dart';
import 'package:highlight/highlight.dart' show highlight, Node;
import 'package:animated_text_kit/animated_text_kit.dart';
import 'package:chart/package/markdown/flutter_markdown.dart';
......@@ -20,6 +22,7 @@ import 'package:intl/intl.dart' as intl;
import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:share_plus/share_plus.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:vibration/vibration.dart';
import 'package:video_player/video_player.dart' as vp;
import '../../pages/home/controller.dart';
......
......@@ -48,6 +48,9 @@ class ChatMessage {
/// Text of the message (optional because you can also just send a media)
String text;
/// 是否在播放
bool isPlaying = false;
VoidCallback? stopCallback = null;
/// Author of the message
ChatUser user;
......
......@@ -9,6 +9,7 @@ class ChartTTS {
double pitch;
String language = "zh-CN";
static ChartTTS tts = ChartTTS();
List<ChatMessage> messages = <ChatMessage>[];
ChartTTS(
{this.voiceName = "zh",
......@@ -25,15 +26,31 @@ class ChartTTS {
FlutterTts get flutterTts => _flutterTts;
Future<void> speak(String message, VoidCallback? onFinishedCallback) async {
Future<void> speak(
ChatMessage message, VoidCallback? onFinishedCallback) async {
messages.forEach((element) {
element.isPlaying = false;
if (element.stopCallback != null) {
element.stopCallback!();
}
});
messages.add(message);
//先停止
await stop();
messages.forEach((element) {
element.isPlaying = false;
});
_flutterTts.setCompletionHandler(() {
if (onFinishedCallback != null) {
message.isPlaying = false;
messages.forEach((element) {
element.isPlaying = false;
});
onFinishedCallback();
}
});
var rev = await _flutterTts.speak(message);
var rev = await _flutterTts.speak(message.text);
message.isPlaying = true;
}
Future<void> stop() async {
......
......@@ -34,6 +34,21 @@ class DefaultMessageText extends StatefulWidget {
class _DefaultMessageTextState extends State<DefaultMessageText> {
CustomPopupMenuController controller = CustomPopupMenuController();
@override
void initState() {
controller.addListener(() {
if (controller.menuIsShowing) {
Vibrate.feedback(FeedbackType.impact);
}
});
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
......@@ -250,14 +265,14 @@ class _DefaultMessageTextState extends State<DefaultMessageText> {
children: <Widget>[
const Icon(
Icons.content_copy,
size: 20,
size: 12,
color: Colors.white,
),
Container(
margin: EdgeInsets.only(top: 2),
child: Text(
"复制",
style: TextStyle(color: Colors.white, fontSize: 12),
style: TextStyle(color: Colors.white, fontSize: 8),
),
),
],
......@@ -276,14 +291,14 @@ class _DefaultMessageTextState extends State<DefaultMessageText> {
children: <Widget>[
const Icon(
Icons.share,
size: 20,
size: 12,
color: Colors.white,
),
Container(
margin: EdgeInsets.only(top: 2),
child: const Text(
"分享",
style: TextStyle(color: Colors.white, fontSize: 12),
style: TextStyle(color: Colors.white, fontSize: 8),
),
),
],
......@@ -393,35 +408,47 @@ class MyStyleSheet extends MarkdownStyleSheet {
class ChartTTSWave extends StatefulWidget {
String text;
ChartTTSWave({Key? key, required this.text}) : super(key: key);
ChatMessage message;
ChartTTSWave({Key? key, required this.text, required this.message}) : super(key: key);
@override
State<ChartTTSWave> createState() => _ChartTTSWaveState();
}
class _ChartTTSWaveState extends State<ChartTTSWave> {
var isPlaying = false;
void stopCallback() {
setState(() {
widget.message.isPlaying = false;
});
}
@override
Widget build(BuildContext context) {
widget.message.stopCallback = stopCallback;
return GestureDetector(
onTap: () async {
ChartTTS.tts.speak(widget.text, () {
ChartTTS.tts.speak(widget.message, () {
setState(() {
isPlaying = false;
// widget.message.isPlaying = false;
});
});
setState(() {
isPlaying = true;
widget.message.isPlaying = true;
});
},
child: isPlaying
child: widget.message.isPlaying
? LoadingAnimationWidget.staggeredDotsWave(
color: Colors.white,
size: 20,
size: 12,
)
: Icon(Icons.record_voice_over_sharp),
: CircleAvatar(
child: Icon(
Icons.record_voice_over_sharp,
size: 24,
),
backgroundColor: Colors.black54,
),
);
}
}
......@@ -168,8 +168,9 @@ class MessageRow extends StatelessWidget {
messageOptions.messageTextBuilder,
)),
Padding(
key: ValueKey(message.hashCode),
padding: EdgeInsets.only(left: 10, top: 15),
child: ChartTTSWave(text: message.text)),
child: ChartTTSWave(text: message.text, message: message,)),
],
)),
if (message.medias != null &&
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment