taafee-mobile/lib/features/chat/presentation_layer/widgets/voice_message.dart
2023-10-17 17:22:55 +03:00

201 lines
7.8 KiB
Dart

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<VoiceMessage> createState() => _VoiceMessageState();
}
class _VoiceMessageState extends State<VoiceMessage> {
final ChatController chatController = Get.find<ChatController>();
final PlayerController playerController = PlayerController();
final HomeController homeController = Get.find<HomeController>();
bool isPlaying = false;
bool isLoading = false;
bool showDefaulWaves = true;
String? voiceUrl;
List<double> 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);
});
}
}