import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:audio_waveforms/audio_waveforms.dart'; import 'package:get/get.dart'; import 'package:taafee_mobile/common/extensions/widget_extension.dart'; import 'package:taafee_mobile/common/widgets/text.dart'; import 'package:taafee_mobile/features/chat/business%20logic%20layer/chat_controller.dart'; import 'package:taafee_mobile/features/chat/data_layer/model/message.dart'; import 'package:taafee_mobile/features/home/business_logic_layer/home_controller.dart'; import '../../../../common/const/const.dart'; class VoiceMessage extends StatefulWidget { VoiceMessage({ super.key, this.file, required this.textFieldFocusNode, required this.messageModel, this.dismissibleKey = const Key('sent'), }); final Key dismissibleKey; final FocusNode textFieldFocusNode; final MessageModel messageModel; File? file; @override State createState() => _VoiceMessageState(); } class _VoiceMessageState extends State { final ChatController chatController = Get.find(); final PlayerController playerController = PlayerController(); final HomeController homeController = Get.find(); bool isPlaying = false; bool isLoading = false; bool showDefaulWaves = true; String? voiceUrl; List waveFormData = Constants.defaulWaveFormData; @override void initState() { setState(() { if (widget.file != null) { playerController.preparePlayer(path: widget.file!.path); showDefaulWaves = false; if (chatController.voiceFiles[widget.messageModel.content] == null) { chatController.voiceFiles[widget.messageModel.content] = widget.file!; } } }); voiceUrl = Domain.chatFiles + widget.messageModel.content; playerController.onCompletion.listen((event) { setState(() { isPlaying = false; }); }); playerController.onPlayerStateChanged.listen((event) { if (event.isPaused || event.isStopped) { setState(() { isPlaying = false; }); } }); super.initState(); } @override Widget build(BuildContext context) { return Obx(() { return Dismissible( confirmDismiss: (direction) async { chatController.updateReplyModel(messageModel: widget.messageModel); if (chatController.isReplying.value == false) { chatController.toggleIsReplying(); } FocusScope.of(context).requestFocus(widget.textFieldFocusNode); return false; }, key: widget.dismissibleKey, onDismissed: null, child: SizedBox( width: Get.width * 0.7, child: Container( decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/images/sent message.png'), fit: BoxFit.fill)), child: SizedBox( width: Get.width, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Row( children: [ if (isLoading) const CircleAvatar( radius: 21.3, backgroundColor: Colors.white, child: CircularProgressIndicator( color: Colors.grey, ), ).paddingOnly(left: 16, top: 16), if (widget.file == null && !isLoading) CircleAvatar( radius: 21.3, backgroundColor: Colors.white, child: const Icon( Icons.download, color: Colors.grey, ).onTap(() async { setState(() { isPlaying = false; isLoading = true; }); widget.file = await chatController.getVoiceFile( id: widget.messageModel.content); chatController .voiceFiles[widget.messageModel.content] = widget.file!; await playerController.preparePlayer( path: widget.file!.path); setState(() { isLoading = false; showDefaulWaves = false; }); }), ).paddingOnly(left: 16, top: 16), if (isPlaying) CircleAvatar( radius: 21.3, backgroundColor: Colors.white, child: const Icon( Icons.stop, color: Colors.grey, ).onTap(() async { setState(() { isPlaying = false; }); await playerController.pausePlayer(); }), ).paddingOnly(left: 16, top: 16), if (!isPlaying && widget.file != null && !isLoading) SvgPicture.asset('assets/icons/play_voice.svg') .paddingOnly(top: 16, left: 16) .onTap(() async { setState(() { isPlaying = true; }); await playerController.startPlayer( finishMode: FinishMode.pause); }), Visibility( visible: showDefaulWaves, child: AudioFileWaveforms( waveformData: waveFormData, size: const Size(160, 50.0), waveformType: WaveformType.fitWidth, playerController: playerController, ).paddingOnly( left: homeController.isArabic.value ? 20 : 8, ), ), Visibility( visible: !showDefaulWaves, child: AudioFileWaveforms( size: const Size(160, 50.0), waveformType: WaveformType.fitWidth, playerController: playerController, ).paddingOnly( left: homeController.isArabic.value ? 20 : 8, ), ), ], ).paddingOnly( right: homeController.isArabic.value ? 36 : 0, ), RegularTextWidget( widget.messageModel.createdAt.toString().substring(11, 16), color: Colors.white, textAlign: TextAlign.right, fontSize: 10, ) .align(alignment: Alignment.bottomRight) .paddingOnly(right: Responsive.isTablet() ? 80 : 40), const SizedBox( height: 16, ), ], ), ).align(alignment: Alignment.centerRight), ).align(alignment: Alignment.centerRight), ).paddingOnly(left: Responsive.isTablet() ? 0 : 70, right: 0), ).align(alignment: Alignment.centerRight); }); } }