// ignore_for_file: invalid_use_of_protected_member import 'dart:io'; import 'package:audio_waveforms/audio_waveforms.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; import 'package:taafee_mobile/common/extensions/widget_extension.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'; import '../../../../common/widgets/text.dart'; class NewVoiceMessage extends StatelessWidget { NewVoiceMessage({ super.key, this.dismissibleKey = const Key('sent'), required this.messageModel, required this.textFieldFocusNode, }); final HomeController homeController = Get.find(); final ChatController chatController = Get.find(); final MessageModel messageModel; final FocusNode textFieldFocusNode; final Key dismissibleKey; @override Widget build(BuildContext context) { PlayerController playerController = chatController.getVoicePlayer(messageModel.content).value; playerController.onCompletion.listen((event) { chatController.updateIsPlaying(messageModel.content, false); }); playerController.onPlayerStateChanged.listen((event) { if (event.isPaused || event.isStopped) { chatController.updateIsPlaying(messageModel.content, false); } }); return Obx(() { return Dismissible( confirmDismiss: (direction) async { chatController.updateReplyModel(messageModel: messageModel); if (chatController.isReplying.value == false) { chatController.toggleIsReplying(); } FocusScope.of(context).requestFocus(textFieldFocusNode); return false; }, key: dismissibleKey, onDismissed: null, child: SizedBox( width: Get.width * 0.58, height: 70, child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: (messageModel.direction == MessageDirection.received) ? Colors.white : AppColors.sentMessageColor, // image: (messageModel.direction == MessageDirection.sent) // ? const DecorationImage( // image: AssetImage('assets/images/sent message.png'), // fit: BoxFit.fill) // : null ), child: SizedBox( width: Get.width, height: 70, child: Column( crossAxisAlignment: (messageModel.direction == MessageDirection.received) ? CrossAxisAlignment.start : CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ Row( children: [ Obx(() { return Visibility( visible: (chatController .isLoadingMap.value[messageModel.content] ?? false), child: CircleAvatar( radius: 21.3, backgroundColor: (messageModel.direction == MessageDirection.received) ? AppColors.borderColor : Colors.white, child: SizedBox( width: 18, height: 18, child: CircularProgressIndicator( color: (messageModel.direction == MessageDirection.received) ? Colors.white : AppColors.borderColor, ), ), ).paddingOnly(left: 16, top: 0), ); }), Obx(() { return Visibility( visible: (chatController .voiceFiles[messageModel.content] == null && ((chatController.isLoadingMap .value[messageModel.content] != null) ? (!chatController.isLoadingMap .value[messageModel.content]!) : true)), child: CircleAvatar( radius: 21.3, backgroundColor: (messageModel.direction == MessageDirection.received) ? AppColors.borderColor : Colors.white, child: Icon( Icons.download, color: (messageModel.direction == MessageDirection.received) ? Colors.white : AppColors.borderColor, ).onTap(() async { chatController.updateIsPlaying( messageModel.content, false); chatController.updateIsLoading( messageModel.content, true); File? file = await chatController.getVoiceFile( id: messageModel.content); chatController.addVoiceFile( messageModel.content, file!); await playerController.preparePlayer( path: file.path); chatController.updateIsLoading( messageModel.content, false); }), ).paddingOnly(left: 16, top: 0), ); }), Obx(() { return Visibility( visible: (chatController .isPlayingMap[messageModel.content] ?? false), child: CircleAvatar( radius: 21.3, backgroundColor: (messageModel.direction == MessageDirection.received) ? AppColors.borderColor : Colors.white, child: Icon( Icons.stop, color: (messageModel.direction == MessageDirection.received) ? Colors.white : AppColors.borderColor, ).onTap(() async { chatController.updateIsPlaying( messageModel.content, false); await playerController.pausePlayer(); }), ).paddingOnly(left: 16, top: 0), ); }), Obx(() { return Visibility( visible: ((chatController .isPlayingMap[messageModel.content] != null ? !chatController .isPlayingMap[messageModel.content]! : true) && chatController.voiceFiles[messageModel.content] != null && ((chatController.isLoadingMap .value[messageModel.content] != null) ? (!chatController.isLoadingMap .value[messageModel.content]!) : true)), child: SvgPicture.asset((messageModel.direction == MessageDirection.received) ? 'assets/icons/play_voice-2.svg' : 'assets/icons/play_voice.svg') .paddingOnly(top: 16, left: 16) .onTap(() async { chatController.updateIsPlaying( messageModel.content, true); await playerController.startPlayer( finishMode: FinishMode.pause); }), ); }), Visibility( visible: chatController.voiceFiles[messageModel.content] == null, child: AudioFileWaveforms( playerWaveStyle: (messageModel.direction == MessageDirection.received) ? PlayerWaveStyle( backgroundColor: Colors.grey, seekLineColor: Colors.grey, fixedWaveColor: Colors.grey, liveWaveColor: AppColors.primeColor, ) : const PlayerWaveStyle(), waveformData: Constants.defaulWaveFormData, size: homeController.isArabic.value ? const Size(118, 30.0) : const Size(130, 30.0), waveformType: WaveformType.long, playerController: playerController, ).paddingOnly( left: homeController.isArabic.value ? 4 : 8, ), ), Visibility( visible: (chatController.voiceFiles[messageModel.content] != null), child: Builder(builder: (context) { try { return AudioFileWaveforms( playerWaveStyle: (messageModel.direction == MessageDirection.received) ? PlayerWaveStyle( backgroundColor: Colors.grey, seekLineColor: Colors.grey, fixedWaveColor: Colors.grey, liveWaveColor: AppColors.primeColor, ) : const PlayerWaveStyle(), size: homeController.isArabic.value ? const Size(118, 30.0) : const Size(130, 30.0), waveformType: WaveformType.long, playerController: playerController, enableSeekGesture: false, ).paddingOnly( left: homeController.isArabic.value ? 4 : 8, ); } on Exception { return AudioFileWaveforms( playerWaveStyle: (messageModel.direction == MessageDirection.received) ? PlayerWaveStyle( liveWaveColor: AppColors.primeColor, backgroundColor: Colors.grey, seekLineColor: Colors.grey, fixedWaveColor: Colors.grey, ) : const PlayerWaveStyle(), enableSeekGesture: false, waveformData: Constants.defaulWaveFormData, size: homeController.isArabic.value ? const Size(118, 30.0) : const Size(130, 30.0), waveformType: WaveformType.long, playerController: playerController, ).paddingOnly( left: homeController.isArabic.value ? 4 : 8, ); } }), ), ], ).paddingOnly( right: homeController.isArabic.value ? 28 : 0, ), RegularTextWidget( messageModel.createdAt.toString().substring(11, 16), color: (messageModel.direction == MessageDirection.sent) ? Colors.white : Colors.grey, textAlign: TextAlign.right, fontSize: 10, ) .align( alignment: (messageModel.direction == MessageDirection.received) ? Alignment.bottomLeft : Alignment.bottomRight) .paddingOnly( right: Responsive.isTablet() ? 80 : 40, left: (messageModel.direction == MessageDirection.received) ? 22 : 0, top: (messageModel.direction == MessageDirection.received) ? 8 : 0, ), ], ).paddingOnly( top: (messageModel.direction == MessageDirection.sent) ? 8 : 0), ).align( alignment: (messageModel.direction == MessageDirection.received) ? Alignment.centerLeft : Alignment.centerRight), ).align( alignment: (messageModel.direction == MessageDirection.received) ? Alignment.centerLeft : Alignment.centerRight), ).paddingOnly( left: Responsive.isTablet() ? 0 : (messageModel.direction == MessageDirection.received) ? 12 : 70, right: 0), ).align( alignment: (messageModel.direction == MessageDirection.received) ? Alignment.centerLeft : Alignment.centerRight); }).paddingOnly(bottom: 12); } }