@@ -6,6 +6,7 @@ import 'package:fluffychat/pages/chat/events/audio_message/audio_player_style.da
66import 'package:fluffychat/pages/chat/events/message/message_style.dart' ;
77import 'package:fluffychat/pages/chat/seen_by_row.dart' ;
88import 'package:fluffychat/presentation/mixins/audio_mixin.dart' ;
9+ import 'package:fluffychat/presentation/mixins/event_filter_mixin.dart' ;
910import 'package:fluffychat/utils/matrix_sdk_extensions/download_file_extension.dart' ;
1011import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart' ;
1112import 'package:fluffychat/utils/platform_infos.dart' ;
@@ -16,14 +17,12 @@ import 'package:fluffychat/widgets/file_widget/file_tile_widget.dart';
1617import 'package:fluffychat/widgets/file_widget/message_file_tile_style.dart' ;
1718import 'package:fluffychat/widgets/matrix.dart' ;
1819import 'package:fluffychat/widgets/twake_components/twake_icon_button.dart' ;
19- import 'package:flutter/foundation.dart' ;
2020import 'package:flutter/material.dart' ;
2121import 'package:intl/intl.dart' ;
2222import 'package:just_audio/just_audio.dart' ;
2323import 'package:linagora_design_flutter/linagora_design_flutter.dart' ;
2424import 'package:matrix/matrix.dart' ;
2525import 'package:fluffychat/generated/l10n/app_localizations.dart' ;
26- import 'package:path_provider/path_provider.dart' ;
2726
2827import 'package:fluffychat/utils/localized_exception_extension.dart' ;
2928import 'package:opus_caf_converter_dart/opus_caf_converter_dart.dart' ;
@@ -49,7 +48,7 @@ class AudioPlayerWidget extends StatefulWidget {
4948enum AudioPlayerStatus { notDownloaded, downloading, downloaded }
5049
5150class AudioPlayerState extends State <AudioPlayerWidget >
52- with AudioMixin , AutomaticKeepAliveClientMixin {
51+ with AudioMixin , AutomaticKeepAliveClientMixin , EventFilterMixin {
5352 final List <double > _calculatedWaveform = [];
5453
5554 final ValueNotifier <Duration > _durationNotifier =
@@ -89,18 +88,18 @@ class AudioPlayerState extends State<AudioPlayerWidget>
8988 ScaffoldMessenger .of (matrix.context).clearMaterialBanners ();
9089 });
9190 if (matrix.voiceMessageEvent.value? .eventId == widget.event.eventId) {
92- if (matrix.audioPlayer.isAtEndPosition) {
91+ if (matrix.audioPlayer? .isAtEndPosition == true ) {
9392 matrix.voiceMessageEvent.value = null ;
94- await matrix.audioPlayer.stop ();
95- await matrix.audioPlayer.dispose ();
93+ await matrix.audioPlayer? .stop ();
94+ await matrix.audioPlayer? .dispose ();
9695 matrix.currentAudioStatus.value = AudioPlayerStatus .notDownloaded;
9796 await _onButtonTap ();
9897 return ;
9998 }
100- if (matrix.audioPlayer.playing == true ) {
101- matrix.audioPlayer.pause ();
99+ if (matrix.audioPlayer? .playing == true ) {
100+ matrix.audioPlayer? .pause ();
102101 } else {
103- matrix.audioPlayer.play ().onError ((e, s) {
102+ matrix.audioPlayer? .play ().onError ((e, s) {
104103 Logs ().e ('Could not play audio file' , e, s);
105104 ScaffoldMessenger .of (context).showSnackBar (
106105 SnackBar (
@@ -115,66 +114,15 @@ class AudioPlayerState extends State<AudioPlayerWidget>
115114 return ;
116115 }
117116
118- matrix.voiceMessageEvent.value = widget.event;
119- await matrix.audioPlayer.stop ();
120- await matrix.audioPlayer.dispose ();
121- File ? file;
122- MatrixFile ? matrixFile;
123-
124- matrix.currentAudioStatus.value = AudioPlayerStatus .downloading;
125- try {
126- matrixFile = await widget.event.downloadAndDecryptAttachment ();
127-
128- if (! kIsWeb) {
129- final tempDir = await getTemporaryDirectory ();
130- final fileName = Uri .encodeComponent (
131- widget.event.attachmentOrThumbnailMxcUrl ()! .pathSegments.last,
132- );
133- file = File ('${tempDir .path }/${fileName }_${matrixFile .name }' );
134-
135- await file.writeAsBytes (matrixFile.bytes ?? []);
136-
137- if (Platform .isIOS &&
138- matrixFile.mimeType.toLowerCase () == 'audio/ogg' ) {
139- file = await handleOggAudioFileIniOS (file);
140- }
141- }
142-
143- matrix.currentAudioStatus.value = AudioPlayerStatus .downloaded;
144- } catch (e, s) {
145- Logs ().v ('Could not download audio file' , e, s);
146- ScaffoldMessenger .of (context).showSnackBar (
147- SnackBar (
148- content: Text (e.toLocalizedString (context)),
149- ),
150- );
151- rethrow ;
152- }
153- if (matrix.voiceMessageEvent.value? .eventId != widget.event.eventId) return ;
154- matrix.audioPlayer = AudioPlayer ();
155- matrix.voiceMessageEvent.value = widget.event;
156-
157- if (file != null ) {
158- matrix.audioPlayer.setFilePath (file.path);
159- } else {
160- await matrix.audioPlayer
161- .setAudioSource (MatrixFileAudioSource (matrixFile));
162- }
117+ final audioPending = await initAudioEventsUpToClicked (
118+ client: matrix.client,
119+ room: widget.event.room,
120+ clickedEvent: widget.event,
121+ );
163122
164- // Set up auto-dispose listener managed globally in MatrixState
165- matrix.setupAudioPlayerAutoDispose ();
123+ matrix.voiceMessageEvents.value = audioPending.events;
166124
167- matrix.audioPlayer.play ().onError ((e, s) {
168- Logs ().e ('Could not play audio file' , e, s);
169- ScaffoldMessenger .of (context).showSnackBar (
170- SnackBar (
171- content: Text (
172- e? .toLocalizedString (context) ??
173- L10n .of (context)! .couldNotPlayAudioFile,
174- ),
175- ),
176- );
177- });
125+ matrix.autoPlayAudio (currentEvent: widget.event);
178126 }
179127
180128 Future <File > handleOggAudioFileIniOS (File file) async {
@@ -231,21 +179,23 @@ class AudioPlayerState extends State<AudioPlayerWidget>
231179 @override
232180 void dispose () {
233181 if (! PlatformInfos .isMobile) {
234- // Stop and dispose audio player asynchronously to avoid blocking dispose
235- matrix.audioPlayer.stop ().then ((_) {
236- matrix.audioPlayer.dispose ();
237- }).catchError ((error) {
238- Logs ().e ('Error disposing audio player' , error);
239- });
240-
241- // Schedule value updates for after the current frame to avoid
242- // setState() during widget tree lock
243- WidgetsBinding .instance.addPostFrameCallback ((_) {
244- if (matrix.voiceMessageEvent.value? .eventId == widget.event.eventId) {
182+ // Only dispose if this event is currently playing
183+ if (matrix.voiceMessageEvent.value? .eventId == widget.event.eventId) {
184+ // Stop and dispose audio player asynchronously to avoid blocking
185+ // dispose
186+ matrix.audioPlayer? .stop ().then ((_) {
187+ matrix.audioPlayer? .dispose ();
188+ }).catchError ((error) {
189+ Logs ().e ('Error disposing audio player' , error);
190+ });
191+
192+ // Schedule value updates for after the current frame to avoid
193+ // setState() during widget tree lock
194+ WidgetsBinding .instance.addPostFrameCallback ((_) {
245195 matrix.currentAudioStatus.value = AudioPlayerStatus .notDownloaded;
246196 matrix.voiceMessageEvent.value = null ;
247- }
248- });
197+ });
198+ }
249199 }
250200
251201 super .dispose ();
0 commit comments