From 191bc33eb44673834a633590e3ca169b89ba3a18 Mon Sep 17 00:00:00 2001 From: tanlongsheng <252620078@qq.com> Date: Wed, 21 May 2025 18:24:50 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=82=B9=E5=87=BB=E6=96=87?= =?UTF-8?q?=E5=AD=97=E6=92=AD=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../meeting_details_controller.dart | 7 +- .../meeting/views/meeting_details_view.dart | 123 ++++++++++-------- lib/modules/meeting/views/speech_tab.dart | 52 ++++++-- 3 files changed, 120 insertions(+), 62 deletions(-) diff --git a/lib/modules/meeting/controllers/meeting_details_controller.dart b/lib/modules/meeting/controllers/meeting_details_controller.dart index 4aa2a200a..8f085f76e 100644 --- a/lib/modules/meeting/controllers/meeting_details_controller.dart +++ b/lib/modules/meeting/controllers/meeting_details_controller.dart @@ -25,7 +25,9 @@ class MeetingDetailsController extends GetxController final PlayerController playerController = PlayerController(); RxBool isTop = false.obs; RxInt durationMax = 0.obs; - RxDouble dragOffset = 210.0.w.obs; + RxDouble dragOffset = 210.w.obs; + + RxInt currentDuration = 0.obs; int id = 0; @@ -99,6 +101,9 @@ class MeetingDetailsController extends GetxController ); durationMax.value = await playerController.getDuration(DurationType.max); playerController.setFinishMode(finishMode: FinishMode.pause); + playerController.onCurrentDurationChanged.listen((int position) { + currentDuration.value = position; + }); if (meetingDetails.value.tasktype == 1) { List speakerList = await SqfliteApi.getMeetingSpeaker(id); textList.value = List.from(speakerList); diff --git a/lib/modules/meeting/views/meeting_details_view.dart b/lib/modules/meeting/views/meeting_details_view.dart index 9af120ebb..f6bbd6984 100644 --- a/lib/modules/meeting/views/meeting_details_view.dart +++ b/lib/modules/meeting/views/meeting_details_view.dart @@ -92,14 +92,22 @@ class MeetingDetailsView extends GetView { }, ), 4.horizontalSpace, - AudioFileWaveforms( - size: Size(130.w, 30.w), - playerController: controller.playerController, - playerWaveStyle: PlayerWaveStyle( - fixedWaveColor: Colors.grey[400]!, - liveWaveColor: Colors.red, - seekLineColor: Colors.red, - scaleFactor: 100, + GestureDetector( + onTap: () { + if (controller.isSpeakerText.value) return; + controller.dragOffset.value = 210.w; + controller.isTop.value = false; + }, + child: AudioFileWaveforms( + size: Size(130.w, 30.w), + playerController: controller.playerController, + enableSeekGesture: false, + playerWaveStyle: PlayerWaveStyle( + fixedWaveColor: Colors.grey[400]!, + liveWaveColor: Colors.red, + seekLineColor: Colors.red, + scaleFactor: 100, + ), ), ), ], @@ -203,19 +211,23 @@ class MeetingDetailsView extends GetView { child: Column( children: [ _soundWave(isDarkMode), - Container( - padding: EdgeInsets.symmetric(horizontal: 8.w), - margin: EdgeInsets.symmetric(vertical: 10.w), - child: Obx( - () => Row( - children: [ - _iconItem(Icons.summarize, '概述', 0), - _iconItem(Icons.message, '转写', 1), - _iconItem(Icons.article, '总结', 2), - _iconItem(Icons.lan, '思维导图', 3), - ], - ), - ), + Obx( + () => !controller.isSpeakerText.value + ? Container( + padding: EdgeInsets.symmetric(horizontal: 8.w), + margin: EdgeInsets.symmetric(vertical: 10.w), + child: Obx( + () => Row( + children: [ + _iconItem(Icons.summarize, '概述', 0), + _iconItem(Icons.message, '转写', 1), + _iconItem(Icons.article, '总结', 2), + _iconItem(Icons.lan, '思维导图', 3), + ], + ), + ), + ) + : const SizedBox(), ), ], ), @@ -289,25 +301,20 @@ class MeetingDetailsView extends GetView { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - StreamBuilder( - stream: controller - .playerController.onCurrentDurationChanged, - builder: (context, snapshot) { - final position = snapshot.data ?? 0; - return Text( - DateUtil.formatDateMs( - position, - format: 'HH:mm:ss', - isUtc: true, - ), - style: TextStyle( - color: isDarkMode - ? Colors.grey[400] - : Colors.grey[500], - fontSize: 12.sp, - ), - ); - }, + Obx( + () => Text( + DateUtil.formatDateMs( + controller.currentDuration.value, + format: 'HH:mm:ss', + isUtc: true, + ), + style: TextStyle( + color: isDarkMode + ? Colors.grey[400] + : Colors.grey[500], + fontSize: 12.sp, + ), + ), ), Obx( () => Text( @@ -330,10 +337,20 @@ class MeetingDetailsView extends GetView { Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - Icon( - Icons.replay_10, - color: Colors.black, - size: 30.w, + GestureDetector( + onTap: () { + int progress = + controller.currentDuration.value - 10000; + if (progress < 0) { + progress = 0; + } + controller.playerController.seekTo(progress); + }, + child: Icon( + Icons.replay_10, + color: Colors.black, + size: 30.w, + ), ), StreamBuilder( stream: @@ -356,10 +373,17 @@ class MeetingDetailsView extends GetView { ); }, ), - Icon( - Icons.forward_10, - color: Colors.black, - size: 30.w, + GestureDetector( + onTap: () { + int progress = + controller.currentDuration.value + 10000; + controller.playerController.seekTo(progress); + }, + child: Icon( + Icons.forward_10, + color: Colors.black, + size: 30.w, + ), ), ], ), @@ -382,9 +406,6 @@ class MeetingDetailsView extends GetView { onTap: () { if (isActive) return; controller.tabController.index = index; - controller.isSpeakerText.value = false; - controller.editSpeakerTextId.value = 0; - controller.editSpeakerTextList = []; }, child: Container( height: 45.w, diff --git a/lib/modules/meeting/views/speech_tab.dart b/lib/modules/meeting/views/speech_tab.dart index 94c7debe2..a61ebae6a 100644 --- a/lib/modules/meeting/views/speech_tab.dart +++ b/lib/modules/meeting/views/speech_tab.dart @@ -151,16 +151,46 @@ class SpeechTab extends GetView { ), ); } else { - return Container( - padding: EdgeInsets.symmetric( - horizontal: 14.w, - vertical: 5.w, - ), - child: Text( - item['content'], - style: textStyle, - ), - ); + return Obx(() { + bool isActive = false; + int starttime = item['starttime']; + int endtime = 0; + if (index == controller.textList.length - 1) { + endtime = controller.durationMax.value; + } else { + endtime = controller.textList[index + 1]['starttime']; + } + if (controller.currentDuration.value != 0) { + if (controller.currentDuration.value >= starttime && + controller.currentDuration.value <= endtime) { + isActive = true; + } + } + return GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () { + controller.playerController + .seekTo(item['starttime']); + controller.playerController.startPlayer(); + }, + child: Container( + width: double.infinity, + padding: EdgeInsets.symmetric( + horizontal: 14.w, + vertical: 5.w, + ), + child: Text( + item['content'], + style: TextStyle( + fontSize: 15.sp, + color: isActive ? Colors.red : Colors.black87, + letterSpacing: 0, + height: 1.4, + ), + ), + ), + ); + }); } }), ], @@ -183,6 +213,8 @@ class SpeechTab extends GetView { '编辑', () { controller.isSpeakerText.value = true; + controller.dragOffset.value = 0; + controller.isTop.value = true; }, ), if (controller.meetingDetails.value.tasktype == 1 &&