From 54961c875f1ac3234cbf1a38692e2f8fbdd6f66f Mon Sep 17 00:00:00 2001 From: "Aamir.Muhammad" Date: Sun, 1 Jan 2023 16:02:39 +0300 Subject: [PATCH] Ios Stream Audio --- assets/langs/ar-SA.json | 3 +- assets/langs/en-US.json | 3 +- lib/generated/locale_keys.g.dart | 1 + lib/ui/chat/chat_bubble.dart | 65 ++++++++++++++----- lib/ui/chat/chat_detailed_screen.dart | 1 - lib/ui/chat/chat_home.dart | 2 +- .../search_employee_bottom_sheet.dart | 1 - 7 files changed, 55 insertions(+), 21 deletions(-) diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index c7259fd..60b88a8 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -518,5 +518,6 @@ "winners": "الفائزين!!!", "noUpcoming": "لا يوجد قادم", "fakeLocation": ".لقد تتبعنا أنك تحاول استخدام موقع مزيف! يعتبر هذا مخالفة وقد تم إخطار الموارد البشرية", - "noWinner": "حزين! لم يفز أحد اليوم." + "noWinner": "حزين! لم يفز أحد اليوم.", + "myTeam" : "فريقي" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index f1eac93..10cfbdf 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -518,5 +518,6 @@ "winners": "WINNERS!!!", "noUpcoming": "There is no upcoming", "fakeLocation": "We traced out that you try to use a fake location! This is considered a violation, and HR has been notified.", - "noWinner": "Sad! No one won today." + "noWinner": "Sad! No one won today.", + "myTeam" : "My Team" } \ No newline at end of file diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 1114c23..035d458 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -505,5 +505,6 @@ abstract class LocaleKeys { static const noUpcoming = 'noUpcoming'; static const fakeLocation = 'fakeLocation'; static const noWinner = 'noWinner'; + static const myTeam = 'myTeam'; } diff --git a/lib/ui/chat/chat_bubble.dart b/lib/ui/chat/chat_bubble.dart index 93fea00..ee28c95 100644 --- a/lib/ui/chat/chat_bubble.dart +++ b/lib/ui/chat/chat_bubble.dart @@ -61,11 +61,17 @@ class ChatBubble extends StatelessWidget { required SingleUserChatModel data, }) async { if (data.voice != null && data.voice!.existsSync()) { - await data.voiceController!.setFilePath(data!.voice!.path); await data.voiceController!.setLoopMode(LoopMode.off); - Duration? duration = await data.voiceController!.load(); - await data.voiceController!.seek(duration); - await data.voiceController!.play(); + if (Platform.isIOS) { + Duration? duration = await data.voiceController!.setAudioSource(MyCustomStream(data.voice!.readAsBytesSync())); + await data.voiceController!.seek(duration); + data.voiceController!.play(); + } else { + await data.voiceController!.setFilePath(data!.voice!.path); + Duration? duration = await data.voiceController!.load(); + await data.voiceController!.seek(duration); + await data.voiceController!.play(); + } } else { Utils.showLoading(context); Uint8List encodedString = await ChatApiClient().downloadURL(fileName: data.contant!, fileTypeDescription: provider.getFileTypeDescription(data.fileTypeResponse!.fileTypeName ?? "")); @@ -74,13 +80,19 @@ class ChatBubble extends StatelessWidget { File file = File(path!); await file.readAsBytes(); data.voice = file; - Duration? duration = await data.voiceController!.setFilePath(file.path); - await data.voiceController!.setLoopMode(LoopMode.off); - await data.voiceController!.seek(duration); - await data.voiceController!.setVolume(1.0); - await data.voiceController!.load(); - Utils.hideLoading(context); - await data.voiceController!.play(); + if (Platform.isIOS) { + Duration? duration = await data.voiceController!.setAudioSource(MyCustomStream(encodedString)); + await data.voiceController!.seek(duration); + data.voiceController!.play(); + } else { + Duration? duration = await data.voiceController!.setFilePath(file.path); + await data.voiceController!.setLoopMode(LoopMode.off); + await data.voiceController!.seek(duration); + await data.voiceController!.setVolume(1.0); + await data.voiceController!.load(); + Utils.hideLoading(context); + await data.voiceController!.play(); + } } catch (e) { Utils.hideLoading(context); Utils.showToast(e.toString()); @@ -114,7 +126,7 @@ class ChatBubble extends StatelessWidget { Widget currentUser(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [ + children: [ if (isReplied) ClipRRect( borderRadius: BorderRadius.circular(5.0), @@ -200,7 +212,7 @@ class ChatBubble extends StatelessWidget { ), ), ], - ).paddingOnly(top: 11, left: 13, right: 13, bottom: 5).objectContainerView(disablePadding: true).paddingOnly(left: MediaQuery.of(context).size.width * 0.3); + ).paddingOnly(top: 11, left: 13, right: 13, bottom: 5).objectContainerView(disablePadding: true, radius: 10).paddingOnly(left: MediaQuery.of(context).size.width * 0.3); } Widget receiptUser(BuildContext context) { @@ -340,6 +352,7 @@ class ChatBubble extends StatelessWidget { Widget currentWaveBubble(BuildContext context, SingleUserChatModel data) { return Container( margin: const EdgeInsets.all(0), + constraints: const BoxConstraints(), decoration: BoxDecoration( border: Border( left: BorderSide(width: 6, color: isCurrentUser ? MyColors.gradiantStartColor : MyColors.white), @@ -411,7 +424,7 @@ class ChatBubble extends StatelessWidget { child: const CircularProgressIndicator(), ); } else if (playing != true) { - return Icon( + return const Icon( Icons.play_arrow, size: 30, color: MyColors.lightGreenColor, @@ -419,7 +432,7 @@ class ChatBubble extends StatelessWidget { playVoice(context, data: modelData); }); } else if (processingState != ProcessingState.completed) { - return Icon( + return const Icon( Icons.pause, size: 30, color: MyColors.lightGreenColor, @@ -427,7 +440,7 @@ class ChatBubble extends StatelessWidget { pausePlaying(context, data: modelData); }); } else { - return Icon( + return const Icon( Icons.replay, size: 30, color: MyColors.lightGreenColor, @@ -439,3 +452,23 @@ class ChatBubble extends StatelessWidget { ); } } + +// Feed your own stream of bytes into the player +class MyCustomStream extends StreamAudioSource { + final Uint8List bytes; + + MyCustomStream(this.bytes); + + @override + Future request([int? start, int? end]) async { + start ??= 0; + end ??= bytes.length; + return StreamAudioResponse( + sourceLength: bytes.length, + contentLength: end - start, + offset: start, + stream: Stream.value(bytes.sublist(start, end)), + contentType: 'audio/aac', + ); + } +} diff --git a/lib/ui/chat/chat_detailed_screen.dart b/lib/ui/chat/chat_detailed_screen.dart index 595dc13..f597fe2 100644 --- a/lib/ui/chat/chat_detailed_screen.dart +++ b/lib/ui/chat/chat_detailed_screen.dart @@ -275,7 +275,6 @@ class _ChatDetailScreenState extends State { : null, ), onChanged: (String val) { - print(val.length); if (val.isNotEmpty) { m.isTextMsg = true; } else { diff --git a/lib/ui/chat/chat_home.dart b/lib/ui/chat/chat_home.dart index 49908dd..bbb3048 100644 --- a/lib/ui/chat/chat_home.dart +++ b/lib/ui/chat/chat_home.dart @@ -83,7 +83,7 @@ class _ChatHomeState extends State { children: [ myTab(LocaleKeys.mychats.tr(), 0), myTab(LocaleKeys.favorite.tr(), 1), - AppState().getempStatusIsManager ? myTab("My Team", 2) : const SizedBox(), + AppState().getempStatusIsManager ? myTab(LocaleKeys.myTeam.tr(), 2) : const SizedBox(), ], ), ), diff --git a/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart b/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart index d06bfdc..b20674e 100644 --- a/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart +++ b/lib/widgets/bottom_sheets/search_employee_bottom_sheet.dart @@ -136,7 +136,6 @@ class _SearchEmployeeBottomSheetState extends State { @override void dispose() { - print("// TODO: implement dispose"); super.dispose(); provider.chatUsersList = []; provider.pageNo = 1;