From 05a19d18e3fe112aca8da5ad6c40d25f3d96aa48 Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Fri, 9 Jan 2026 16:19:23 +0800 Subject: [PATCH] =?UTF-8?q?fix(meeting):=20=E4=BF=AE=E5=A4=8D=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E6=93=8D=E4=BD=9C=E6=97=B6=E6=9C=AA=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E5=BD=95=E9=9F=B3=E5=92=8C=E6=A0=87=E9=A2=98=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改返回逻辑,确保在返回前保存录音和标题变更 修复底部弹窗显示时未暂停录音的问题 --- .../meeting_record_controller.dart | 48 +++++++++---------- .../meeting/views/meeting_record_view.dart | 26 +++++----- 2 files changed, 36 insertions(+), 38 deletions(-) diff --git a/lib/modules/meeting/controllers/meeting_record_controller.dart b/lib/modules/meeting/controllers/meeting_record_controller.dart index 277c1c998..e3f867cac 100644 --- a/lib/modules/meeting/controllers/meeting_record_controller.dart +++ b/lib/modules/meeting/controllers/meeting_record_controller.dart @@ -25,7 +25,7 @@ enum TimerStatus { /// 负责会议记录的状态管理、音频处理、语音识别和UI交互 class MeetingRecordController extends GetxController with GetTickerProviderStateMixin { - // Services + // 服务 final AsrService _asrService = Get.find(); final BleManager _bleManager = Get.find(); @@ -45,7 +45,7 @@ class MeetingRecordController extends GetxController final RecorderController waveformController = RecorderController(); - // Transcription content + // 转写内容 final RxString intermediateContent = ''.obs; final RxString finalContent = ''.obs; @@ -57,7 +57,7 @@ class MeetingRecordController extends GetxController late FocusNode titleFocusNode; final Future appDocDir = getApplicationDocumentsDirectory(); - // Timing variables + // 计时变量 Timer? _timer; int _elapsedMilliseconds = 0; int? _lastStartTime; @@ -107,19 +107,19 @@ class MeetingRecordController extends GetxController } } - /// Initializes UI controllers and focus nodes + /// 初始化 UI 控制器和焦点节点 void _initializeComponents() { titleEditingController = TextEditingController(text: fileName.value); titleFocusNode = FocusNode(); titleFocusNode.addListener(_handleTitleFocusChange); } - /// Sets up initial state from navigation arguments + /// 根据路由参数设置初始状态 void _setupFromArguments() { final Map args = Get.arguments ?? {}; audioType.value = args['audioTypes'] ?? 0; - // Set default filename based on audio type + // 根据音频类型设置默认文件名 switch (audioType.value) { case 0: fileName.value = "liveRecording".tr; //对应中文:现场录音 @@ -134,7 +134,7 @@ class MeetingRecordController extends GetxController newName.value = fileName.value; } - /// Cleans up resources when controller is disposed + /// 控制器销毁时清理资源 void _cleanupResources() { _timer?.cancel(); _stopWaveformTimer(); @@ -156,14 +156,14 @@ class MeetingRecordController extends GetxController waveformController.dispose(); } - /// Handles focus changes in title text field + /// 处理标题输入框焦点变化 void _handleTitleFocusChange() { if (!titleFocusNode.hasFocus && isEditingTitle.value) { saveTitleChange(); } } - /// Starts title editing mode + /// 开始标题编辑模式 void startTitleEditing() { isEditingTitle.value = true; titleEditingController.text = fileName.value; @@ -173,7 +173,7 @@ class MeetingRecordController extends GetxController }); } - /// Saves new title and exits editing mode + /// 保存新标题后退出编辑状态 Future saveTitleChange() async { isEditingTitle.value = true; if (isEditingTitle.value) { @@ -183,12 +183,12 @@ class MeetingRecordController extends GetxController } } - /// Toggles visibility of transcribed text content + /// 切换转写文本内容的显示状态 Future toggleTextDisplay() async { showTextContent.toggle(); } - /// Toggles important mark status + /// 切换重要标记状态 void toggleMarked() => isMarked.toggle(); /// 格式化时间为 MM:SS.S 显示格式 @@ -204,7 +204,7 @@ class MeetingRecordController extends GetxController '.${centiseconds.toString()}'; } - /// Starts/resumes recording based on current state + /// 根据当前状态开始或恢复录音 Future toggleRecording() async { // 等待权限请求完成并获取结果 final bool granted = await _requestRecordPermission(); @@ -229,7 +229,7 @@ class MeetingRecordController extends GetxController } } - /// Starts recording session + /// 开始录音会话 Future _startRecording() async { // Prepare storage directory final appDir = await appDocDir; @@ -260,7 +260,7 @@ class MeetingRecordController extends GetxController }); isRecording.value = true; - // Update state + // 更新录音状态 fileName.value = fullFileName; newName.value = fullFileName; titleEditingController.text = fullFileName; @@ -272,7 +272,7 @@ class MeetingRecordController extends GetxController startTimer(); } - /// Activates appropriate hardware service based on audio type + /// 根据音频类型启动对应的硬件服务 void _startHardwareServices() { switch (audioType.value) { case 0: @@ -289,7 +289,7 @@ class MeetingRecordController extends GetxController } } - /// Pauses current recording session + /// 暂停当前录音会话 Future _pauseRecording() async { await _asrService.pauseRecord(); _stopWaveformTimer(); @@ -297,7 +297,7 @@ class MeetingRecordController extends GetxController pauseTimer(); } - /// Resumes paused recording session + /// 恢复已暂停的录音会话 Future _resumeRecording() async { await _asrService.resumeRecord(); _startWaveformTimer(); @@ -370,7 +370,7 @@ class MeetingRecordController extends GetxController return (rms / 32768.0).clamp(0.0, 1.0); } - /// Saves recording and cleans up resources + /// 保存录音并清理相关资源 Future saveRecording() async { resetTimer(); _stopWaveformTimer(); @@ -380,7 +380,7 @@ class MeetingRecordController extends GetxController if (!isRecording.value) return; await _asrService.stopRecord(true); - // Rename file if title was edited + // 如果标题被修改则重命名文件 if (fileName.value != newName.value) { final appDir = await appDocDir; final dir = Directory("${appDir.path}/MeetingAudio/"); @@ -408,7 +408,7 @@ class MeetingRecordController extends GetxController _resetWaveform(); } - /// Resets controller to initial state + /// 将控制器重置到初始状态 void _resetToDefaultState() { switch (audioType.value) { case 0: @@ -427,7 +427,7 @@ class MeetingRecordController extends GetxController isMarked.value = false; } - /// TIMER CONTROL SECTION /// + /// 计时器控制部分 /// /// 启动定时器 void startTimer() { @@ -449,7 +449,7 @@ class MeetingRecordController extends GetxController } } - /// Pauses active timer + /// 暂停当前计时器 void pauseTimer() { if (timerStatus.value == TimerStatus.running) { timerStatus.value = TimerStatus.paused; @@ -462,7 +462,7 @@ class MeetingRecordController extends GetxController } } - /// Resets timer to initial state + /// 将计时器重置到初始状态 void resetTimer() { _timer?.cancel(); _timer = null; diff --git a/lib/modules/meeting/views/meeting_record_view.dart b/lib/modules/meeting/views/meeting_record_view.dart index 8456c1fd6..356fb7565 100644 --- a/lib/modules/meeting/views/meeting_record_view.dart +++ b/lib/modules/meeting/views/meeting_record_view.dart @@ -13,13 +13,11 @@ class MeetingRecordView extends GetView { Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; - return PopScope( - onPopInvokedWithResult: (didPop, result) async { - if (didPop) { - // 在返回时执行保存操作 - //controller.saveTitleChange(); - //await controller.saveRecording(); - } + return WillPopScope( + onWillPop: () async { + await controller.saveTitleChange(); + await controller.saveRecording(); + return true; }, child: Scaffold( appBar: AppBar( @@ -29,12 +27,7 @@ class MeetingRecordView extends GetView { color: isDarkMode ? Colors.white : Colors.black, size: 20.sp, ), - onPressed: () async { - // 在返回按钮点击时执行保存操作 - controller.saveTitleChange(); - await controller.saveRecording(); - Get.back(); - }, + onPressed: () => Navigator.of(context).maybePop(), ), title: Obx(() { if (controller.isEditingTitle.value) { @@ -411,7 +404,12 @@ class MeetingRecordView extends GetView { } // 底部编辑弹窗 - void _bottomSheet(BuildContext context, bool isDarkMode) { + void _bottomSheet(BuildContext context, bool isDarkMode) async { + //如果当前计时器在运行,先暂停录音,避免编辑时继续录音 + if (controller.timerStatus.value == TimerStatus.running) { + await controller.toggleRecording(); + } + Get.bottomSheet( Container( padding: EdgeInsets.only(