From 964b20e074cf81adf200c548d8a8f70b2f49e4ce Mon Sep 17 00:00:00 2001 From: ggurdin Date: Mon, 23 Jun 2025 15:30:40 -0400 Subject: [PATCH] chore: fix audio ID issue --- lib/pages/chat/chat.dart | 4 +- lib/pages/chat/events/message_content.dart | 5 +- .../toolbar/widgets/select_mode_buttons.dart | 96 +++++++++++-------- 3 files changed, 63 insertions(+), 42 deletions(-) diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 35639c8cf..e2cd8b515 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -488,7 +488,9 @@ class ChatController extends State final botAudioEvent = timeline.events!.firstWhereOrNull( (e) => e.senderId == BotName.byEnvironment && - e.content.tryGet('msgtype') == MessageTypes.Audio, + e.content.tryGet('msgtype') == MessageTypes.Audio && + DateTime.now().difference(e.originServerTs) < + const Duration(seconds: 10), ); if (botAudioEvent == null) return; diff --git a/lib/pages/chat/events/message_content.dart b/lib/pages/chat/events/message_content.dart index 028d86e66..b57d8472d 100644 --- a/lib/pages/chat/events/message_content.dart +++ b/lib/pages/chat/events/message_content.dart @@ -222,10 +222,11 @@ class MessageContent extends StatelessWidget { fontSize: fontSize, // #Pangea chatController: controller, - eventId: event.eventId, + eventId: + "${event.eventId}${overlayController != null ? '_overlay' : ''}", roomId: event.room.id, senderId: event.senderId, - autoplay: overlayController != null, + autoplay: overlayController != null && isTransitionAnimation, // Pangea# ); } diff --git a/lib/pangea/toolbar/widgets/select_mode_buttons.dart b/lib/pangea/toolbar/widgets/select_mode_buttons.dart index b90611076..43759a1a1 100644 --- a/lib/pangea/toolbar/widgets/select_mode_buttons.dart +++ b/lib/pangea/toolbar/widgets/select_mode_buttons.dart @@ -93,34 +93,13 @@ class SelectModeButtonsState extends State { Completer? _transcriptionCompleter; - AudioPlayer? get _audioPlayer => Matrix.of(context).audioPlayer!; + MatrixState? matrix; @override void initState() { super.initState(); - final matrix = Matrix.of(context); - matrix.audioPlayer?.dispose(); - matrix.audioPlayer = AudioPlayer(); - matrix.voiceMessageEventId.value = - widget.overlayController.pangeaMessageEvent?.eventId; - - _onPlayerStateChanged = _audioPlayer?.playerStateStream.listen((state) { - if (state.processingState == ProcessingState.completed) { - _updateMode(null); - } - setState(() {}); - }); - - _onAudioPositionChanged ??= _audioPlayer?.positionStream.listen((state) { - if (_audioBytes?.tokens != null) { - widget.overlayController.highlightCurrentText( - state.inMilliseconds, - _audioBytes!.tokens!, - ); - } - }); - + matrix = Matrix.of(context); if (messageEvent?.isAudioMessage == true) { _fetchTranscription(); } @@ -128,9 +107,9 @@ class SelectModeButtonsState extends State { @override void dispose() { - _audioPlayer?.dispose(); - Matrix.of(context).audioPlayer = null; - Matrix.of(context).voiceMessageEventId.value = null; + matrix?.audioPlayer?.dispose(); + matrix?.audioPlayer = null; + matrix?.voiceMessageEventId.value = null; _onPlayerStateChanged?.cancel(); _onAudioPositionChanged?.cancel(); @@ -162,8 +141,8 @@ class SelectModeButtonsState extends State { if (mode == null) { setState(() { - _audioPlayer?.stop(); - _audioPlayer?.seek(null); + matrix?.audioPlayer?.stop(); + matrix?.audioPlayer?.seek(null); _selectedMode = null; }); return; @@ -178,8 +157,8 @@ class SelectModeButtonsState extends State { _playAudio(); return; } else { - _audioPlayer?.stop(); - _audioPlayer?.seek(null); + matrix?.audioPlayer?.stop(); + matrix?.audioPlayer?.seek(null); } if (_selectedMode == SelectMode.practice) { @@ -243,13 +222,52 @@ class SelectModeButtonsState extends State { } Future _playAudio() async { - try { - if (_audioPlayer != null && _audioPlayer!.playerState.playing) { - await _audioPlayer?.pause(); + final playerID = + "${widget.overlayController.pangeaMessageEvent?.eventId}_button"; + + if (matrix?.audioPlayer != null && + matrix?.voiceMessageEventId.value == playerID) { + // If the audio player is already initialized and playing the same message, pause it + if (matrix!.audioPlayer!.playerState.playing) { + await matrix?.audioPlayer?.pause(); return; - } else if (_audioPlayer?.position != Duration.zero) { + } + // If the audio player is paused, resume it + await matrix?.audioPlayer?.play(); + return; + } + + matrix?.audioPlayer?.dispose(); + matrix?.audioPlayer = AudioPlayer(); + matrix?.voiceMessageEventId.value = + widget.overlayController.pangeaMessageEvent?.eventId; + + _onPlayerStateChanged = + matrix?.audioPlayer?.playerStateStream.listen((state) { + if (state.processingState == ProcessingState.completed) { + _updateMode(null); + } + setState(() {}); + }); + + _onAudioPositionChanged ??= + matrix?.audioPlayer?.positionStream.listen((state) { + if (_audioBytes?.tokens != null) { + widget.overlayController.highlightCurrentText( + state.inMilliseconds, + _audioBytes!.tokens!, + ); + } + }); + + try { + if (matrix?.audioPlayer != null && + matrix!.audioPlayer!.playerState.playing) { + await matrix?.audioPlayer?.pause(); + return; + } else if (matrix?.audioPlayer?.position != Duration.zero) { TtsController.stop(); - await _audioPlayer?.play(); + await matrix?.audioPlayer?.play(); return; } @@ -260,9 +278,9 @@ class SelectModeButtonsState extends State { if (_audioBytes == null) return; if (_audioFile != null) { - await _audioPlayer?.setFilePath(_audioFile!.path); + await matrix?.audioPlayer?.setFilePath(_audioFile!.path); } else { - await _audioPlayer?.setAudioSource( + await matrix?.audioPlayer?.setAudioSource( BytesAudioSource( _audioBytes!.bytes, _audioBytes!.mimeType, @@ -271,7 +289,7 @@ class SelectModeButtonsState extends State { } TtsController.stop(); - _audioPlayer?.play(); + matrix?.audioPlayer?.play(); } catch (e, s) { setState(() => _audioError = e.toString()); ErrorHandler.logError( @@ -441,7 +459,7 @@ class SelectModeButtonsState extends State { if (mode == SelectMode.audio) { return Icon( - _audioPlayer?.playerState.playing == true + matrix?.audioPlayer?.playerState.playing == true ? Icons.pause_outlined : Icons.volume_up, size: 20,