diff --git a/lib/models/message.dart b/lib/models/message.dart index 1cb6c05..63768e8 100644 --- a/lib/models/message.dart +++ b/lib/models/message.dart @@ -175,7 +175,7 @@ class AudioClipContent { final String id; final String assetUri; - AudioClipContent({required this.id, required this.assetUri}); + const AudioClipContent({required this.id, required this.assetUri}); factory AudioClipContent.fromMap(Map map) { return AudioClipContent( @@ -190,7 +190,7 @@ class MarkReadBatch { final List ids; final DateTime readTime; - MarkReadBatch({required this.senderId, required this.ids, required this.readTime}); + const MarkReadBatch({required this.senderId, required this.ids, required this.readTime}); Map toMap() { return { diff --git a/lib/widgets/messages/message_audio_player.dart b/lib/widgets/messages/message_audio_player.dart index 191c9eb..18ef94f 100644 --- a/lib/widgets/messages/message_audio_player.dart +++ b/lib/widgets/messages/message_audio_player.dart @@ -17,22 +17,46 @@ class MessageAudioPlayer extends StatefulWidget { State createState() => _MessageAudioPlayerState(); } -class _MessageAudioPlayerState extends State { +class _MessageAudioPlayerState extends State with WidgetsBindingObserver { final AudioPlayer _audioPlayer = AudioPlayer(); double _sliderValue = 0; @override void initState() { super.initState(); + WidgetsBinding.instance.addObserver(this); if (Platform.isAndroid) { + //TODO: Add caching of audio-files _audioPlayer.setUrl( Aux.neosDbToHttp(AudioClipContent - .fromMap(jsonDecode(widget.message.content)) - .assetUri), + .fromMap(jsonDecode(widget.message.content)).assetUri), preload: true).whenComplete(() => _audioPlayer.setLoopMode(LoopMode.off)); } } + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + if (state == AppLifecycleState.paused) { + _audioPlayer.stop(); + } + } + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + _audioPlayer.setUrl( + Aux.neosDbToHttp(AudioClipContent + .fromMap(jsonDecode(widget.message.content)).assetUri), + preload: true).whenComplete(() => _audioPlayer.setLoopMode(LoopMode.off)); + } + + @override + void dispose() { + WidgetsBinding.instance.removeObserver(this); + _audioPlayer.dispose(); + super.dispose(); + } + Widget _createErrorWidget(String error) { return Padding( padding: const EdgeInsets.all(8.0), @@ -114,8 +138,8 @@ class _MessageAudioPlayerState extends State { StreamBuilder( stream: _audioPlayer.positionStream, builder: (context, snapshot) { - _sliderValue = (_audioPlayer.position.inMilliseconds / - (_audioPlayer.duration?.inMilliseconds ?? 0)).clamp(0, 1); + _sliderValue = _audioPlayer.duration == null ? 0 : (_audioPlayer.position.inMilliseconds / + (_audioPlayer.duration!.inMilliseconds)).clamp(0, 1); return StatefulBuilder( // Not sure if this makes sense here... builder: (context, setState) { return SliderTheme( diff --git a/lib/widgets/messages/message_bubble.dart b/lib/widgets/messages/message_bubble.dart index e1f9ea9..8f07a6e 100644 --- a/lib/widgets/messages/message_bubble.dart +++ b/lib/widgets/messages/message_bubble.dart @@ -29,8 +29,7 @@ class MessageBubble extends StatelessWidget { child: Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8), child: switch (message.type) { - MessageType.sessionInvite => - MessageSessionInvite(message: message, foregroundColor: foregroundColor,), + MessageType.sessionInvite => MessageSessionInvite(message: message, foregroundColor: foregroundColor,), MessageType.object => MessageAsset(message: message, foregroundColor: foregroundColor,), MessageType.sound => MessageAudioPlayer(message: message, foregroundColor: foregroundColor,), MessageType.unknown || MessageType.text => MessageText(message: message, foregroundColor: foregroundColor,)