From 0f192b5118c8d0a0874ef656b3244b6b3eca11e4 Mon Sep 17 00:00:00 2001 From: adrianoct42 Date: Tue, 6 Aug 2024 17:36:03 -0300 Subject: [PATCH 01/20] feat: new DSEndRecord widget (work in progress), new DSMessageContentType --- lib/blip_ds.dart | 1 + .../utils/ds_message_content_type.util.dart | 1 + .../widgets/chat/ds_end_record.widget.dart | 113 ++++++++++++++++++ .../sample_message_bubble.showcase.dart | 4 + 4 files changed, 119 insertions(+) create mode 100644 lib/src/widgets/chat/ds_end_record.widget.dart diff --git a/lib/blip_ds.dart b/lib/blip_ds.dart index c558504a..2f29ea40 100644 --- a/lib/blip_ds.dart +++ b/lib/blip_ds.dart @@ -133,6 +133,7 @@ export 'src/widgets/chat/ds_contact_message_bubble.widget.dart' show DSContactMessageBubble; export 'src/widgets/chat/ds_delivery_report_icon.widget.dart' show DSDeliveryReportIcon; +export 'src/widgets/chat/ds_end_record.widget.dart' show DSEndRecord; export 'src/widgets/chat/ds_file_message_bubble.widget.dart' show DSFileMessageBubble; export 'src/widgets/chat/ds_image_message_bubble.widget.dart' diff --git a/lib/src/utils/ds_message_content_type.util.dart b/lib/src/utils/ds_message_content_type.util.dart index eb5d4ab9..2dc3f87b 100644 --- a/lib/src/utils/ds_message_content_type.util.dart +++ b/lib/src/utils/ds_message_content_type.util.dart @@ -13,4 +13,5 @@ abstract class DSMessageContentType { static const String location = 'application/vnd.lime.location+json'; static const String applicationJson = 'application/json'; static const String reply = 'application/vnd.lime.reply+json'; + static const String callsMedia = 'application/vnd.iris.calls.media+json'; } diff --git a/lib/src/widgets/chat/ds_end_record.widget.dart b/lib/src/widgets/chat/ds_end_record.widget.dart new file mode 100644 index 00000000..d570fffd --- /dev/null +++ b/lib/src/widgets/chat/ds_end_record.widget.dart @@ -0,0 +1,113 @@ +import 'package:flutter/material.dart'; + +import '../../../blip_ds.dart'; + +class DSEndRecord extends StatelessWidget { + final Uri uri; + final DSAlign align; + final List borderRadius; + final DSMessageBubbleStyle style; + final String? uniqueId; + final bool shouldAuthenticate; + final DSReplyContent? replyContent; + + DSEndRecord({ + super.key, + required this.uri, + required this.align, + this.uniqueId, + this.replyContent, + this.borderRadius = const [DSBorderRadius.all], + this.shouldAuthenticate = false, + final DSMessageBubbleStyle? style, + }) : style = style ?? DSMessageBubbleStyle(); + + @override + Widget build(BuildContext context) { + final isDefaultBubbleColors = style.isDefaultBubbleBackground(align); + final isLightBubbleBackground = style.isLightBubbleBackground(align); + + return DSMessageBubble( + borderRadius: borderRadius, + align: align, + replyContent: replyContent, + style: style, + padding: EdgeInsets.zero, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 16, + horizontal: 8, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Row( + children: [ + const SizedBox( + width: 8, + ), + Container( + width: 40, + height: 40, + decoration: BoxDecoration( + color: DSColors.success, + borderRadius: BorderRadius.circular(10), + ), + child: const Icon( + DSIcons.voip_calling_outline, + color: DSColors.contentDefault, + ), + ), + const SizedBox( + width: 8, + ), + Column( + children: [ + DSHeadlineSmallText( + "Ligação", + ), + DSBodyText( + "Finalizada", + ), + ], + ), + const SizedBox( + width: 16, + ), + DSBodyText("+55 31 999999999"), + ], + ), + const SizedBox( + height: 16, + ), + Center( + child: DSMessageBubble( + align: align, + style: style, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + DSBodyText("Carregar gravação"), + Container( + decoration: BoxDecoration( + color: DSColors.contentDefault, + borderRadius: BorderRadius.circular(10), + ), + child: IconButton( + onPressed: () {}, + icon: const Icon( + DSIcons.refresh_outline, + color: DSColors.neutralLightSnow, + ), + ), + ) + ], + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart b/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart index 76ff0196..d5d342fe 100644 --- a/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart +++ b/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart @@ -53,6 +53,10 @@ class SampleMessageBubbleShowcase extends StatelessWidget { return Obx( () => Column( children: [ + DSEndRecord( + uri: Uri.parse(_sampleAudio), + align: DSAlign.left, + ), DSTextMessageBubble( text: 'Essa foto é linda', align: DSAlign.left, From 37fdad0b81b99dadb0a1909439820c26237e1280 Mon Sep 17 00:00:00 2001 From: adrianoct42 Date: Wed, 7 Aug 2024 19:03:18 -0300 Subject: [PATCH 02/20] refactor: widget name changed to DSEndCallsMessageBubble, better widget design on aforementioned widget. --- lib/blip_ds.dart | 3 +- .../ds_end_calls_message_bubble.widget.dart | 158 ++++++++++++++++++ .../widgets/chat/ds_end_record.widget.dart | 113 ------------- .../sample_message_bubble.showcase.dart | 2 +- 4 files changed, 161 insertions(+), 115 deletions(-) create mode 100644 lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart delete mode 100644 lib/src/widgets/chat/ds_end_record.widget.dart diff --git a/lib/blip_ds.dart b/lib/blip_ds.dart index 2f29ea40..58384d0f 100644 --- a/lib/blip_ds.dart +++ b/lib/blip_ds.dart @@ -133,7 +133,8 @@ export 'src/widgets/chat/ds_contact_message_bubble.widget.dart' show DSContactMessageBubble; export 'src/widgets/chat/ds_delivery_report_icon.widget.dart' show DSDeliveryReportIcon; -export 'src/widgets/chat/ds_end_record.widget.dart' show DSEndRecord; +export 'src/widgets/chat/ds_end_calls_message_bubble.widget.dart' + show DSEndCallsMessageBubble; export 'src/widgets/chat/ds_file_message_bubble.widget.dart' show DSFileMessageBubble; export 'src/widgets/chat/ds_image_message_bubble.widget.dart' diff --git a/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart b/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart new file mode 100644 index 00000000..bc2c92f6 --- /dev/null +++ b/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart @@ -0,0 +1,158 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../../blip_ds.dart'; + +class DSEndCallsMessageBubble extends StatelessWidget { + final Uri uri; + final DSAlign align; + final List borderRadius; + final DSMessageBubbleStyle style; + final String? callStatus; + final Function? onAsyncFetchSession; + + DSEndCallsMessageBubble({ + super.key, + required this.uri, + required this.align, + this.borderRadius = const [DSBorderRadius.all], + final DSMessageBubbleStyle? style, + this.callStatus, + this.onAsyncFetchSession, + }) : style = style ?? DSMessageBubbleStyle(); + + @override + Widget build(BuildContext context) { + final colorText = style.isLightBubbleBackground(align) + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow; + final colorContainer = style.isLightBubbleBackground(align) + ? DSColors.surface3 + : DSColors.neutralDarkDesk; + final callRecordText = Rx("Carregar gravação"); + final isLoadingRecording = Rx(false); + + return DSMessageBubble( + borderRadius: borderRadius, + align: align, + style: style, + padding: EdgeInsets.zero, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 16, + horizontal: 8, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Row( + children: [ + const SizedBox( + width: 8, + ), + Container( + width: 40, + height: 40, + decoration: BoxDecoration( + color: + (callStatus == 'confirmed' || callStatus == 'answered') + ? DSColors.success + : DSColors.error, + borderRadius: BorderRadius.circular(10), + ), + child: Icon( + (callStatus == 'confirmed' || callStatus == 'answered' + ? DSIcons.voip_calling_outline + : DSIcons.voip_ended_outline), + color: DSColors.contentDefault, + ), + ), + const SizedBox( + width: 8, + ), + Column( + children: [ + DSHeadlineSmallText( + "Ligação", + color: colorText, + ), + DSBodyText( + color: colorText, + callStatus == 'confirmed' || callStatus == 'answered' + ? "Finalizada" + : (callStatus == 'rejected' + ? "Cancelada" + : "Não atendida"), + ), + ], + ), + const SizedBox( + width: 16, + ), + DSBodyText( + "+55 31 999999999", + color: colorText, + ), + ], + ), + const SizedBox( + height: 16, + ), + Container( + decoration: BoxDecoration( + color: colorContainer, + borderRadius: BorderRadius.circular( + 10.0, + ), + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16.0, + ), + child: Obx( + () => Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Visibility( + visible: isLoadingRecording.value ? true : false, + child: const DSSpinnerLoading(), + ), + DSBodyText( + callRecordText.value, + color: colorText, + ), + Container( + height: 50, + decoration: BoxDecoration( + color: DSColors.contentDefault, + borderRadius: BorderRadius.circular( + 10.0, + ), + ), + child: Visibility( + visible: isLoadingRecording.value ? false : true, + child: IconButton( + onPressed: () async { + isLoadingRecording.value = true; + callRecordText.value = "Preparando gravação..."; + //await onAsyncFetchSession(); + await Future.delayed(const Duration(seconds: 3)); + isLoadingRecording.value = false; + callRecordText.value = "Carregar gravação"; + }, + icon: const Icon(DSIcons.refresh_outline, + color: DSColors.neutralLightSnow), + ), + ), + ) + ], + ), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/src/widgets/chat/ds_end_record.widget.dart b/lib/src/widgets/chat/ds_end_record.widget.dart deleted file mode 100644 index d570fffd..00000000 --- a/lib/src/widgets/chat/ds_end_record.widget.dart +++ /dev/null @@ -1,113 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../../blip_ds.dart'; - -class DSEndRecord extends StatelessWidget { - final Uri uri; - final DSAlign align; - final List borderRadius; - final DSMessageBubbleStyle style; - final String? uniqueId; - final bool shouldAuthenticate; - final DSReplyContent? replyContent; - - DSEndRecord({ - super.key, - required this.uri, - required this.align, - this.uniqueId, - this.replyContent, - this.borderRadius = const [DSBorderRadius.all], - this.shouldAuthenticate = false, - final DSMessageBubbleStyle? style, - }) : style = style ?? DSMessageBubbleStyle(); - - @override - Widget build(BuildContext context) { - final isDefaultBubbleColors = style.isDefaultBubbleBackground(align); - final isLightBubbleBackground = style.isLightBubbleBackground(align); - - return DSMessageBubble( - borderRadius: borderRadius, - align: align, - replyContent: replyContent, - style: style, - padding: EdgeInsets.zero, - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 16, - horizontal: 8, - ), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Row( - children: [ - const SizedBox( - width: 8, - ), - Container( - width: 40, - height: 40, - decoration: BoxDecoration( - color: DSColors.success, - borderRadius: BorderRadius.circular(10), - ), - child: const Icon( - DSIcons.voip_calling_outline, - color: DSColors.contentDefault, - ), - ), - const SizedBox( - width: 8, - ), - Column( - children: [ - DSHeadlineSmallText( - "Ligação", - ), - DSBodyText( - "Finalizada", - ), - ], - ), - const SizedBox( - width: 16, - ), - DSBodyText("+55 31 999999999"), - ], - ), - const SizedBox( - height: 16, - ), - Center( - child: DSMessageBubble( - align: align, - style: style, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - DSBodyText("Carregar gravação"), - Container( - decoration: BoxDecoration( - color: DSColors.contentDefault, - borderRadius: BorderRadius.circular(10), - ), - child: IconButton( - onPressed: () {}, - icon: const Icon( - DSIcons.refresh_outline, - color: DSColors.neutralLightSnow, - ), - ), - ) - ], - ), - ), - ), - ], - ), - ), - ); - } -} diff --git a/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart b/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart index d5d342fe..0531dc20 100644 --- a/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart +++ b/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart @@ -53,7 +53,7 @@ class SampleMessageBubbleShowcase extends StatelessWidget { return Obx( () => Column( children: [ - DSEndRecord( + DSEndCallsMessageBubble( uri: Uri.parse(_sampleAudio), align: DSAlign.left, ), From 58471594b06c6c724434cf8feef9b83fb08a6e29 Mon Sep 17 00:00:00 2001 From: adrianoct42 Date: Thu, 8 Aug 2024 15:00:20 -0300 Subject: [PATCH 03/20] refactor: some variable name changes, padding added to elevate cell number position, removed Visibility widget. --- .../ds_end_calls_message_bubble.widget.dart | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart b/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart index bc2c92f6..fba3643b 100644 --- a/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart @@ -23,10 +23,10 @@ class DSEndCallsMessageBubble extends StatelessWidget { @override Widget build(BuildContext context) { - final colorText = style.isLightBubbleBackground(align) + final colorsText = style.isLightBubbleBackground(align) ? DSColors.neutralDarkCity : DSColors.neutralLightSnow; - final colorContainer = style.isLightBubbleBackground(align) + final colorsContainer = style.isLightBubbleBackground(align) ? DSColors.surface3 : DSColors.neutralDarkDesk; final callRecordText = Rx("Carregar gravação"); @@ -74,10 +74,10 @@ class DSEndCallsMessageBubble extends StatelessWidget { children: [ DSHeadlineSmallText( "Ligação", - color: colorText, + color: colorsText, ), DSBodyText( - color: colorText, + color: colorsText, callStatus == 'confirmed' || callStatus == 'answered' ? "Finalizada" : (callStatus == 'rejected' @@ -89,9 +89,14 @@ class DSEndCallsMessageBubble extends StatelessWidget { const SizedBox( width: 16, ), - DSBodyText( - "+55 31 999999999", - color: colorText, + Padding( + padding: const EdgeInsets.only( + bottom: 24.0, + ), + child: DSBodyText( + "+55 31 999999999", + color: colorsText, + ), ), ], ), @@ -100,7 +105,7 @@ class DSEndCallsMessageBubble extends StatelessWidget { ), Container( decoration: BoxDecoration( - color: colorContainer, + color: colorsContainer, borderRadius: BorderRadius.circular( 10.0, ), @@ -113,13 +118,10 @@ class DSEndCallsMessageBubble extends StatelessWidget { () => Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Visibility( - visible: isLoadingRecording.value ? true : false, - child: const DSSpinnerLoading(), - ), + if (isLoadingRecording.value) const DSSpinnerLoading(), DSBodyText( callRecordText.value, - color: colorText, + color: colorsText, ), Container( height: 50, From daa6d45e44ae213c0a8918c39a79715a8c1f3a29 Mon Sep 17 00:00:00 2001 From: adrianoct42 Date: Thu, 8 Aug 2024 15:56:20 -0300 Subject: [PATCH 04/20] refactor: IconButton changed to DSButton to reflect better Figma's design. --- .../ds_end_calls_message_bubble.widget.dart | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart b/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart index fba3643b..611a45ae 100644 --- a/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart @@ -113,6 +113,7 @@ class DSEndCallsMessageBubble extends StatelessWidget { child: Padding( padding: const EdgeInsets.symmetric( horizontal: 16.0, + vertical: 4.0, ), child: Obx( () => Row( @@ -126,24 +127,35 @@ class DSEndCallsMessageBubble extends StatelessWidget { Container( height: 50, decoration: BoxDecoration( - color: DSColors.contentDefault, + color: colorsContainer, borderRadius: BorderRadius.circular( 10.0, ), ), child: Visibility( visible: isLoadingRecording.value ? false : true, - child: IconButton( - onPressed: () async { - isLoadingRecording.value = true; - callRecordText.value = "Preparando gravação..."; - //await onAsyncFetchSession(); - await Future.delayed(const Duration(seconds: 3)); - isLoadingRecording.value = false; - callRecordText.value = "Carregar gravação"; - }, - icon: const Icon(DSIcons.refresh_outline, - color: DSColors.neutralLightSnow), + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 4.0, + ), + child: DSButton( + foregroundColor: Colors.transparent, + backgroundColor: Colors.transparent, + borderColor: DSColors.neutralLightSnow, + onPressed: () async { + isLoadingRecording.value = true; + callRecordText.value = "Preparando gravação..."; + //await onAsyncFetchSession(); + await Future.delayed( + const Duration(seconds: 3)); + isLoadingRecording.value = false; + callRecordText.value = "Carregar gravação"; + }, + leadingIcon: const Icon( + DSIcons.refresh_outline, + color: DSColors.neutralLightSnow, + ), + ), ), ), ) From 3b925029859f8c0c17f99e5201a7a148033e2952 Mon Sep 17 00:00:00 2001 From: Andre Rossi Date: Wed, 14 Aug 2024 11:10:38 -0300 Subject: [PATCH 05/20] feat: add audio player to calls end bubble --- lib/blip_ds.dart | 1 + .../themes/colors/ds_dark_colors.theme.dart | 11 +- .../ds_end_calls_message_bubble.widget.dart | 380 +++++++++++------- lib/src/widgets/utils/ds_card.widget.dart | 12 + .../widgets/utils/ds_group_card.widget.dart | 3 + sample/android/app/build.gradle | 2 +- .../sample_message_bubble.showcase.dart | 3 +- 7 files changed, 265 insertions(+), 147 deletions(-) diff --git a/lib/blip_ds.dart b/lib/blip_ds.dart index 58384d0f..cbcd01e8 100644 --- a/lib/blip_ds.dart +++ b/lib/blip_ds.dart @@ -58,6 +58,7 @@ export 'src/services/ds_auth.service.dart' show DSAuthService; export 'src/services/ds_bottom_sheet.service.dart' show DSBottomSheetService; export 'src/services/ds_dialog.service.dart' show DSDialogService; export 'src/services/ds_file.service.dart' show DSFileService; +export 'src/services/ds_localization.service.dart' show DSLocalizationService; export 'src/services/ds_media_format.service.dart' show DSMediaFormatService; export 'src/services/ds_toast.service.dart' show DSToastService; export 'src/themes/colors/ds_colors.theme.dart' show DSColors; diff --git a/lib/src/themes/colors/ds_dark_colors.theme.dart b/lib/src/themes/colors/ds_dark_colors.theme.dart index 768fa719..66405d27 100644 --- a/lib/src/themes/colors/ds_dark_colors.theme.dart +++ b/lib/src/themes/colors/ds_dark_colors.theme.dart @@ -2,14 +2,15 @@ import 'package:flutter/material.dart'; /// All Dark [Color] constants that are used by this Design System. abstract class DSDarkColors { + static const Color surfacePositive = Color(0xFF01562F); static const Color surface0 = Color(0xFF424242); - static const Color surface1 = Color(0xFF292929); + static const Color surface1 = Color(0xFF393939); static const Color surface3 = Color(0xFF141414); - static const Color contentDefault = Color(0xFFF6F6F6); + static const Color contentDefault = Color(0xFFFFFFFF); + static const Color success = Color(0xFF355E4B); + static const Color positive = Color(0xFF6BFFBC); + static const Color error = Color(0xFF7B3D3D); static const Color extendBlue = Color(0xFF1968F0); static const Color extendGreen = Color(0xFF35DE90); - static const Color success = Color(0xFF355E4B); - static const Color positive = Color(0xFF01562F); - static const Color error = Color(0xFF7B3D3D); } diff --git a/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart b/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart index 611a45ae..bc6f55cd 100644 --- a/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart @@ -1,172 +1,272 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; -import 'package:get/get.dart'; -import '../../../blip_ds.dart'; +import '../../enums/ds_align.enum.dart'; +import '../../enums/ds_border_radius.enum.dart'; +import '../../extensions/ds_localization.extension.dart'; +import '../../extensions/ds_string.extension.dart'; +import '../../models/ds_message_bubble_style.model.dart'; +import '../../themes/colors/ds_colors.theme.dart'; +import '../../themes/icons/ds_icons.dart'; +import '../animations/ds_spinner_loading.widget.dart'; +import '../buttons/ds_button.widget.dart'; +import '../texts/ds_caption_small_text.widget.dart'; +import '../texts/ds_caption_text.widget.dart'; +import 'audio/ds_audio_player.widget.dart'; +import 'ds_message_bubble.widget.dart'; class DSEndCallsMessageBubble extends StatelessWidget { - final Uri uri; final DSAlign align; final List borderRadius; final DSMessageBubbleStyle style; - final String? callStatus; - final Function? onAsyncFetchSession; + final Map content; + final Future Function(String)? onAsyncFetchSession; + final StreamController _streamController = StreamController(); + final Map? translations; + + bool get _isCallAnswered => ['completed', 'answer'].contains( + content['status'].toString().toLowerCase(), + ); + + bool get _isInbound => + content['direction'].toString().toLowerCase() == 'inbound'; + + bool get _isLightBubbleBackground => style.isLightBubbleBackground(align); + bool get _isDefaultBubbleColors => style.isDefaultBubbleBackground(align); + + Color get _foregroundColor => _isLightBubbleBackground + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow; DSEndCallsMessageBubble({ super.key, - required this.uri, required this.align, + required this.content, + required this.onAsyncFetchSession, this.borderRadius = const [DSBorderRadius.all], - final DSMessageBubbleStyle? style, - this.callStatus, - this.onAsyncFetchSession, + DSMessageBubbleStyle? style, + this.translations, }) : style = style ?? DSMessageBubbleStyle(); @override Widget build(BuildContext context) { - final colorsText = style.isLightBubbleBackground(align) - ? DSColors.neutralDarkCity - : DSColors.neutralLightSnow; - final colorsContainer = style.isLightBubbleBackground(align) - ? DSColors.surface3 - : DSColors.neutralDarkDesk; - final callRecordText = Rx("Carregar gravação"); - final isLoadingRecording = Rx(false); - return DSMessageBubble( borderRadius: borderRadius, align: align, style: style, - padding: EdgeInsets.zero, - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 16, - horizontal: 8, - ), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Row( - children: [ - const SizedBox( - width: 8, - ), - Container( - width: 40, - height: 40, - decoration: BoxDecoration( - color: - (callStatus == 'confirmed' || callStatus == 'answered') - ? DSColors.success - : DSColors.error, - borderRadius: BorderRadius.circular(10), - ), - child: Icon( - (callStatus == 'confirmed' || callStatus == 'answered' - ? DSIcons.voip_calling_outline - : DSIcons.voip_ended_outline), - color: DSColors.contentDefault, - ), - ), - const SizedBox( - width: 8, - ), - Column( - children: [ - DSHeadlineSmallText( - "Ligação", - color: colorsText, - ), - DSBodyText( - color: colorsText, - callStatus == 'confirmed' || callStatus == 'answered' - ? "Finalizada" - : (callStatus == 'rejected' - ? "Cancelada" - : "Não atendida"), - ), - ], - ), - const SizedBox( - width: 16, - ), - Padding( - padding: const EdgeInsets.only( - bottom: 24.0, - ), - child: DSBodyText( - "+55 31 999999999", - color: colorsText, - ), - ), - ], - ), - const SizedBox( - height: 16, - ), - Container( - decoration: BoxDecoration( - color: colorsContainer, - borderRadius: BorderRadius.circular( - 10.0, - ), - ), - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16.0, - vertical: 4.0, - ), - child: Obx( - () => Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + children: [ + Row( children: [ - if (isLoadingRecording.value) const DSSpinnerLoading(), - DSBodyText( - callRecordText.value, - color: colorsText, - ), - Container( - height: 50, - decoration: BoxDecoration( - color: colorsContainer, - borderRadius: BorderRadius.circular( - 10.0, - ), - ), - child: Visibility( - visible: isLoadingRecording.value ? false : true, - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 4.0, - ), - child: DSButton( - foregroundColor: Colors.transparent, - backgroundColor: Colors.transparent, - borderColor: DSColors.neutralLightSnow, - onPressed: () async { - isLoadingRecording.value = true; - callRecordText.value = "Preparando gravação..."; - //await onAsyncFetchSession(); - await Future.delayed( - const Duration(seconds: 3)); - isLoadingRecording.value = false; - callRecordText.value = "Carregar gravação"; - }, - leadingIcon: const Icon( - DSIcons.refresh_outline, - color: DSColors.neutralLightSnow, + Padding( + padding: const EdgeInsets.only(right: 8.0), + child: Column( + children: [ + Container( + decoration: BoxDecoration( + color: _isCallAnswered + ? DSColors.success + : DSColors.error, + borderRadius: const BorderRadius.all( + Radius.circular( + 8.0, + ), + ), + ), + width: 30, + height: 30, + child: Icon( + _isCallAnswered + ? _isInbound + ? DSIcons.voip_receiving_outline + : DSIcons.voip_calling_outline + : DSIcons.voip_ended_outline, + size: 20.0, ), ), - ), + ], ), - ) + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DSCaptionText( + 'calls.voice-text'.translate(), + fontWeight: FontWeight.bold, + color: _foregroundColor, + ), + DSCaptionSmallText( + _isCallAnswered + ? 'calls.answered'.translate() + : 'calls.unanswered'.translate(), + color: _foregroundColor, + ), + ], + ), ], ), + ], + ), + Flexible( + child: Column( + children: [ + FutureBuilder( + future: + content['identification'].toString().asPhoneNumber(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + return DSCaptionSmallText( + snapshot.data, + color: _foregroundColor, + ); + } + return const DSSpinnerLoading(); + }, + ) + ], ), ), - ), - ], - ), + ], + ), + if (_isCallAnswered && onAsyncFetchSession != null) + StreamBuilder( + stream: _streamController.stream, + builder: (_, __) { + return FutureBuilder( + future: onAsyncFetchSession!( + content['sessionId'], + ), + builder: (_, snapshot) { + return switch (snapshot.connectionState) { + ConnectionState.waiting => _buildLoading(), + ConnectionState.done => snapshot.hasError + ? _buildError() + : snapshot.data?.isEmpty ?? true + ? const SizedBox.shrink() + : _buildAudioPlayer(snapshot.data!), + _ => const SizedBox.shrink(), + }; + }, + ); + }, + ) + ], ), ); } + + Widget _buildContainer(final Widget child) => SizedBox( + height: 60.0, + child: Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Container( + decoration: BoxDecoration( + color: _isLightBubbleBackground + ? DSColors.neutralLightWhisper + : DSColors.neutralDarkDesk, + borderRadius: const BorderRadius.all( + Radius.circular( + 8.0, + ), + ), + ), + child: child, + ), + ), + ); + + Widget _buildAudioPlayer(final String data) => _buildContainer( + Padding( + padding: const EdgeInsets.only(right: 8.0), + child: DSAudioPlayer( + uri: Uri.parse(data), + controlForegroundColor: _isLightBubbleBackground + ? DSColors.neutralDarkRooftop + : DSColors.neutralLightSnow, + labelColor: _isLightBubbleBackground + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow, + bufferActiveTrackColor: _isLightBubbleBackground + ? DSColors.neutralMediumWave + : DSColors.neutralMediumElephant, + bufferInactiveTrackColor: _isLightBubbleBackground + ? DSColors.neutralDarkRooftop + : DSColors.neutralLightBox, + sliderActiveTrackColor: _isLightBubbleBackground + ? DSColors.primaryNight + : DSColors.primaryLight, + sliderThumbColor: _isLightBubbleBackground + ? DSColors.neutralDarkRooftop + : DSColors.neutralLightSnow, + speedForegroundColor: _isLightBubbleBackground + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow, + speedBorderColor: _isLightBubbleBackground + ? _isDefaultBubbleColors + ? DSColors.neutralMediumSilver + : DSColors.neutralDarkCity + : _isDefaultBubbleColors + ? DSColors.disabledText + : DSColors.neutralLightSnow, + ), + ), + ); + + Widget _buildLoading() => _buildContainer( + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + const DSSpinnerLoading(), + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: DSCaptionText( + 'calls.preparing-record'.translate(), + color: _foregroundColor, + ), + ), + ], + ), + ), + ); + + Widget _buildError() => _buildContainer( + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + DSCaptionText( + 'calls.load-record'.translate(), + color: _foregroundColor, + ), + DSButton( + onPressed: () => _streamController.add(true), + borderColor: _isLightBubbleBackground + ? DSColors.neutralMediumSilver + : DSColors.disabledText, + foregroundColor: _isLightBubbleBackground + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow, + backgroundColor: _isLightBubbleBackground + ? DSColors.neutralLightWhisper + : DSColors.neutralDarkDesk, + trailingIcon: const Icon( + DSIcons.refresh_outline, + size: 25.0, + ), + autoSize: true, + ) + ], + ), + ), + ); } diff --git a/lib/src/widgets/utils/ds_card.widget.dart b/lib/src/widgets/utils/ds_card.widget.dart index 1faa9e49..9a6acc35 100644 --- a/lib/src/widgets/utils/ds_card.widget.dart +++ b/lib/src/widgets/utils/ds_card.widget.dart @@ -18,6 +18,7 @@ import '../chat/audio/ds_audio_message_bubble.widget.dart'; import '../chat/ds_application_json_message_bubble.widget.dart'; import '../chat/ds_carrousel.widget.dart'; import '../chat/ds_contact_message_bubble.widget.dart'; +import '../chat/ds_end_calls_message_bubble.widget.dart'; import '../chat/ds_file_message_bubble.widget.dart'; import '../chat/ds_image_message_bubble.widget.dart'; import '../chat/ds_location_message_bubble.widget.dart'; @@ -49,6 +50,7 @@ class DSCard extends StatelessWidget { this.showRequestLocationButton = false, this.replyContent, this.isUploading = false, + this.onAsyncFetchSession, }) : style = style ?? DSMessageBubbleStyle(); final String type; @@ -66,6 +68,7 @@ class DSCard extends StatelessWidget { final bool showRequestLocationButton; final DSReplyContent? replyContent; final bool isUploading; + final Future Function(String)? onAsyncFetchSession; @override Widget build(BuildContext context) { @@ -167,6 +170,15 @@ class DSCard extends StatelessWidget { avatarConfig: avatarConfig, ); + case DSMessageContentType.callsMedia: + return DSEndCallsMessageBubble( + align: align, + borderRadius: borderRadius, + style: style, + content: content, + onAsyncFetchSession: onAsyncFetchSession, + ); + default: return DSUnsupportedContentMessageBubble( align: align, diff --git a/lib/src/widgets/utils/ds_group_card.widget.dart b/lib/src/widgets/utils/ds_group_card.widget.dart index 25d297e6..f8c01753 100644 --- a/lib/src/widgets/utils/ds_group_card.widget.dart +++ b/lib/src/widgets/utils/ds_group_card.widget.dart @@ -65,6 +65,7 @@ class DSGroupCard extends StatefulWidget { DSMessageBubbleStyle? style, bool Function(DSMessageItem, DSMessageItem)? compareMessages, ScrollController? scrollController, + this.onAsyncFetchSession, }) : compareMessages = compareMessages ?? _defaultCompareMessageFuntion, style = style ?? DSMessageBubbleStyle(), scrollController = scrollController ?? ScrollController(); @@ -82,6 +83,7 @@ class DSGroupCard extends StatefulWidget { final void Function()? onInfinitScroll; final bool shrinkWrap; final ScrollController scrollController; + final Future Function(String)? onAsyncFetchSession; @override State createState() => _DSGroupCardState(); @@ -264,6 +266,7 @@ class _DSGroupCardState extends State { messageId: message.id, customer: message.customer, isUploading: message.isUploading, + onAsyncFetchSession: widget.onAsyncFetchSession, ); final isLastMsg = msgCount == length; diff --git a/sample/android/app/build.gradle b/sample/android/app/build.gradle index f4d361ea..40c52f3b 100644 --- a/sample/android/app/build.gradle +++ b/sample/android/app/build.gradle @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion flutter.compileSdkVersion + compileSdkVersion 34 ndkVersion flutter.ndkVersion compileOptions { diff --git a/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart b/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart index 0531dc20..c1654ceb 100644 --- a/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart +++ b/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart @@ -54,7 +54,8 @@ class SampleMessageBubbleShowcase extends StatelessWidget { () => Column( children: [ DSEndCallsMessageBubble( - uri: Uri.parse(_sampleAudio), + content: const {'identification': '55996226444'}, + onAsyncFetchSession: null, align: DSAlign.left, ), DSTextMessageBubble( From 2b33c53404b013172baa5b16f81fce3b32cba415 Mon Sep 17 00:00:00 2001 From: Andre Rossi Date: Wed, 14 Aug 2024 11:11:15 -0300 Subject: [PATCH 06/20] feat: add localization service --- lib/src/extensions/ds_localization.extension.dart | 10 ++++++++++ lib/src/services/ds_localization.service.dart | 13 +++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 lib/src/extensions/ds_localization.extension.dart create mode 100644 lib/src/services/ds_localization.service.dart diff --git a/lib/src/extensions/ds_localization.extension.dart b/lib/src/extensions/ds_localization.extension.dart new file mode 100644 index 00000000..0d423a25 --- /dev/null +++ b/lib/src/extensions/ds_localization.extension.dart @@ -0,0 +1,10 @@ +import '../services/ds_localization.service.dart'; + +extension DSLocalizationExtension on String { + translate() { + final locale = DSLocalizationService.locale ?? 'pt_BR'; + final translations = + DSLocalizationService.translations?[locale.toString()] ?? {}; + return translations[this] ?? this; + } +} diff --git a/lib/src/services/ds_localization.service.dart b/lib/src/services/ds_localization.service.dart new file mode 100644 index 00000000..67432dc6 --- /dev/null +++ b/lib/src/services/ds_localization.service.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; + +abstract class DSLocalizationService { + static Locale? _locale; + static final Map _translations = {}; + + static setLocale(final Locale locale) => _locale = locale; + static setTranslations(final Map translations) => + _translations.addAll(translations); + + static Locale? get locale => _locale; + static Map? get translations => _translations; +} From cfb73d7546aea4da4cb08b681335963e6bd854ad Mon Sep 17 00:00:00 2001 From: adrianoct42 Date: Mon, 19 Aug 2024 16:17:28 -0300 Subject: [PATCH 07/20] chore: new DSCallsMediaMessage model, new Enums added, DSEndCallsMessageBubble better optimized to reflect figma instructions --- lib/blip_ds.dart | 4 + lib/src/enums/ds_call_direction.enum.dart | 4 + lib/src/enums/ds_call_provider.enum.dart | 4 + lib/src/enums/ds_call_type.enum.dart | 4 + .../models/ds_calls_media_message.model.dart | 38 ++++++++++ .../ds_end_calls_message_bubble.widget.dart | 74 ++++++++----------- 6 files changed, 84 insertions(+), 44 deletions(-) create mode 100644 lib/src/enums/ds_call_direction.enum.dart create mode 100644 lib/src/enums/ds_call_provider.enum.dart create mode 100644 lib/src/enums/ds_call_type.enum.dart create mode 100644 lib/src/models/ds_calls_media_message.model.dart diff --git a/lib/blip_ds.dart b/lib/blip_ds.dart index cbcd01e8..abad13bf 100644 --- a/lib/blip_ds.dart +++ b/lib/blip_ds.dart @@ -2,6 +2,9 @@ library blip_ds; export 'src/enums/ds_align.enum.dart' show DSAlign; export 'src/enums/ds_border_radius.enum.dart' show DSBorderRadius; +export 'src/enums/ds_call_direction.enum.dart' show DSCallDirection; +export 'src/enums/ds_call_provider.enum.dart' show DSCallProvider; +export 'src/enums/ds_call_type.enum.dart' show DSCallType; export 'src/enums/ds_delivery_report_status.enum.dart' show DSDeliveryReportStatus; export 'src/enums/ds_input_container_shape.enum.dart' @@ -17,6 +20,7 @@ export 'src/extensions/ds_border_radius.extension.dart' export 'src/extensions/ds_delivery_report_status.extension.dart' show DSDeliveryReportStatusExtension; export 'src/extensions/ds_string.extension.dart' show DSStringExtension; +export 'src/models/ds_calls_media_message.model.dart' show DSCallsMediaMessage; export 'src/models/ds_message_bubble_avatar_config.model.dart' show DSMessageBubbleAvatarConfig; export 'src/models/ds_message_bubble_style.model.dart' diff --git a/lib/src/enums/ds_call_direction.enum.dart b/lib/src/enums/ds_call_direction.enum.dart new file mode 100644 index 00000000..b9c14542 --- /dev/null +++ b/lib/src/enums/ds_call_direction.enum.dart @@ -0,0 +1,4 @@ +enum DSCallDirection { + outgoing, + incoming, +} diff --git a/lib/src/enums/ds_call_provider.enum.dart b/lib/src/enums/ds_call_provider.enum.dart new file mode 100644 index 00000000..c20790b7 --- /dev/null +++ b/lib/src/enums/ds_call_provider.enum.dart @@ -0,0 +1,4 @@ +enum DSCallProvider { + mobcall, + whatsapp, +} diff --git a/lib/src/enums/ds_call_type.enum.dart b/lib/src/enums/ds_call_type.enum.dart new file mode 100644 index 00000000..f0c5d1df --- /dev/null +++ b/lib/src/enums/ds_call_type.enum.dart @@ -0,0 +1,4 @@ +enum DSCallType { + voice, + video, +} diff --git a/lib/src/models/ds_calls_media_message.model.dart b/lib/src/models/ds_calls_media_message.model.dart new file mode 100644 index 00000000..b59d6ab2 --- /dev/null +++ b/lib/src/models/ds_calls_media_message.model.dart @@ -0,0 +1,38 @@ +import '../enums/ds_call_direction.enum.dart'; +import '../enums/ds_call_provider.enum.dart'; +import '../enums/ds_call_type.enum.dart'; + +class DSCallsMediaMessage { + DSCallType? type; + String sessionId; + DSCallProvider? provider; + DSCallDirection direction; + String? ticketId; + String status; + String identification; + String? media; + int? callDuration; + + DSCallsMediaMessage({ + this.type, + required this.sessionId, + this.provider, + required this.direction, + this.ticketId, + required this.status, + required this.identification, + this.media, + this.callDuration, + }); + + DSCallsMediaMessage.fromJson(Map json) + : type = json['type'], + sessionId = json['sessionId'], + provider = json['provider'], + direction = json['direction'], + ticketId = json['ticketId'], + status = json['status'], + identification = json['identification'], + media = json['media'], + callDuration = json['callDuration']; +} diff --git a/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart b/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart index bc6f55cd..c72cf9ec 100644 --- a/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart @@ -2,35 +2,25 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import '../../enums/ds_align.enum.dart'; -import '../../enums/ds_border_radius.enum.dart'; +import '../../../blip_ds.dart'; import '../../extensions/ds_localization.extension.dart'; -import '../../extensions/ds_string.extension.dart'; -import '../../models/ds_message_bubble_style.model.dart'; -import '../../themes/colors/ds_colors.theme.dart'; -import '../../themes/icons/ds_icons.dart'; -import '../animations/ds_spinner_loading.widget.dart'; -import '../buttons/ds_button.widget.dart'; -import '../texts/ds_caption_small_text.widget.dart'; -import '../texts/ds_caption_text.widget.dart'; -import 'audio/ds_audio_player.widget.dart'; -import 'ds_message_bubble.widget.dart'; +import '../../models/ds_calls_media_message.model.dart'; class DSEndCallsMessageBubble extends StatelessWidget { final DSAlign align; final List borderRadius; final DSMessageBubbleStyle style; - final Map content; + final DSCallsMediaMessage content; final Future Function(String)? onAsyncFetchSession; final StreamController _streamController = StreamController(); final Map? translations; bool get _isCallAnswered => ['completed', 'answer'].contains( - content['status'].toString().toLowerCase(), + content.status.toString().toLowerCase(), ); bool get _isInbound => - content['direction'].toString().toLowerCase() == 'inbound'; + content.direction.toString().toLowerCase() == 'inbound'; bool get _isLightBubbleBackground => style.isLightBubbleBackground(align); bool get _isDefaultBubbleColors => style.isDefaultBubbleBackground(align); @@ -68,39 +58,34 @@ class DSEndCallsMessageBubble extends StatelessWidget { children: [ Padding( padding: const EdgeInsets.only(right: 8.0), - child: Column( - children: [ - Container( - decoration: BoxDecoration( - color: _isCallAnswered - ? DSColors.success - : DSColors.error, - borderRadius: const BorderRadius.all( - Radius.circular( - 8.0, - ), - ), - ), - width: 30, - height: 30, - child: Icon( - _isCallAnswered - ? _isInbound - ? DSIcons.voip_receiving_outline - : DSIcons.voip_calling_outline - : DSIcons.voip_ended_outline, - size: 20.0, + child: Container( + decoration: BoxDecoration( + color: _isCallAnswered + ? DSColors.success + : DSColors.error, + borderRadius: const BorderRadius.all( + Radius.circular( + 8.0, ), ), - ], + ), + width: 40, + height: 40, + child: Icon( + _isCallAnswered + ? _isInbound + ? DSIcons.voip_receiving_outline + : DSIcons.voip_calling_outline + : DSIcons.voip_ended_outline, + size: 24.0, + ), ), ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - DSCaptionText( + DSHeadlineSmallText( 'calls.voice-text'.translate(), - fontWeight: FontWeight.bold, color: _foregroundColor, ), DSCaptionSmallText( @@ -119,8 +104,7 @@ class DSEndCallsMessageBubble extends StatelessWidget { child: Column( children: [ FutureBuilder( - future: - content['identification'].toString().asPhoneNumber(), + future: content.identification.toString().asPhoneNumber(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { return DSCaptionSmallText( @@ -142,7 +126,7 @@ class DSEndCallsMessageBubble extends StatelessWidget { builder: (_, __) { return FutureBuilder( future: onAsyncFetchSession!( - content['sessionId'], + content.sessionId, ), builder: (_, snapshot) { return switch (snapshot.connectionState) { @@ -231,6 +215,7 @@ class DSEndCallsMessageBubble extends StatelessWidget { child: DSCaptionText( 'calls.preparing-record'.translate(), color: _foregroundColor, + fontWeight: DSFontWeights.semiBold, ), ), ], @@ -247,6 +232,7 @@ class DSEndCallsMessageBubble extends StatelessWidget { DSCaptionText( 'calls.load-record'.translate(), color: _foregroundColor, + fontWeight: DSFontWeights.semiBold, ), DSButton( onPressed: () => _streamController.add(true), @@ -261,7 +247,7 @@ class DSEndCallsMessageBubble extends StatelessWidget { : DSColors.neutralDarkDesk, trailingIcon: const Icon( DSIcons.refresh_outline, - size: 25.0, + size: 24.0, ), autoSize: true, ) From fca86e430228c2626af362aab1104e4fdcbcd2a9 Mon Sep 17 00:00:00 2001 From: Andre Rossi Date: Tue, 20 Aug 2024 11:27:48 -0300 Subject: [PATCH 08/20] refactor: improve code readability --- lib/blip_ds.dart | 7 +- lib/src/enums/ds_call_direction.enum.dart | 5 +- lib/src/enums/ds_call_provider.enum.dart | 3 +- lib/src/enums/ds_call_status.enum.dart | 6 + lib/src/enums/ds_call_type.enum.dart | 1 + lib/src/extensions/ds_enum.extension.dart | 12 + .../models/ds_calls_media_message.model.dart | 51 ++-- .../ds_end_calls_message_bubble.widget.dart | 276 ++++++++++++++++++ ..._end_calls_recording_container.widget.dart | 35 +++ .../ds_end_calls_message_bubble.widget.dart | 258 ---------------- lib/src/widgets/utils/ds_card.widget.dart | 5 +- sample/assets/ds_localization.json | 24 ++ sample/lib/main.dart | 107 ++++--- .../sample_message_bubble.showcase.dart | 39 ++- sample/pubspec.lock | 2 +- sample/pubspec.yaml | 1 + 16 files changed, 498 insertions(+), 334 deletions(-) create mode 100644 lib/src/enums/ds_call_status.enum.dart create mode 100644 lib/src/extensions/ds_enum.extension.dart create mode 100644 lib/src/widgets/chat/calls/ds_end_calls_message_bubble.widget.dart create mode 100644 lib/src/widgets/chat/calls/ds_end_calls_recording_container.widget.dart delete mode 100644 lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart create mode 100644 sample/assets/ds_localization.json diff --git a/lib/blip_ds.dart b/lib/blip_ds.dart index abad13bf..f359d86c 100644 --- a/lib/blip_ds.dart +++ b/lib/blip_ds.dart @@ -2,9 +2,6 @@ library blip_ds; export 'src/enums/ds_align.enum.dart' show DSAlign; export 'src/enums/ds_border_radius.enum.dart' show DSBorderRadius; -export 'src/enums/ds_call_direction.enum.dart' show DSCallDirection; -export 'src/enums/ds_call_provider.enum.dart' show DSCallProvider; -export 'src/enums/ds_call_type.enum.dart' show DSCallType; export 'src/enums/ds_delivery_report_status.enum.dart' show DSDeliveryReportStatus; export 'src/enums/ds_input_container_shape.enum.dart' @@ -131,6 +128,8 @@ export 'src/widgets/buttons/ds_tertiary_button.widget.dart' export 'src/widgets/chat/audio/ds_audio_message_bubble.widget.dart' show DSAudioMessageBubble; export 'src/widgets/chat/audio/ds_audio_player.widget.dart' show DSAudioPlayer; +export 'src/widgets/chat/calls/ds_end_calls_message_bubble.widget.dart' + show DSEndCallsMessageBubble; export 'src/widgets/chat/ds_application_json_message_bubble.widget.dart' show DSApplicationJsonMessageBubble; export 'src/widgets/chat/ds_carrousel.widget.dart' show DSCarrousel; @@ -138,8 +137,6 @@ export 'src/widgets/chat/ds_contact_message_bubble.widget.dart' show DSContactMessageBubble; export 'src/widgets/chat/ds_delivery_report_icon.widget.dart' show DSDeliveryReportIcon; -export 'src/widgets/chat/ds_end_calls_message_bubble.widget.dart' - show DSEndCallsMessageBubble; export 'src/widgets/chat/ds_file_message_bubble.widget.dart' show DSFileMessageBubble; export 'src/widgets/chat/ds_image_message_bubble.widget.dart' diff --git a/lib/src/enums/ds_call_direction.enum.dart b/lib/src/enums/ds_call_direction.enum.dart index b9c14542..4b529a78 100644 --- a/lib/src/enums/ds_call_direction.enum.dart +++ b/lib/src/enums/ds_call_direction.enum.dart @@ -1,4 +1,5 @@ enum DSCallDirection { - outgoing, - incoming, + outbound, + inbound, + unknown, } diff --git a/lib/src/enums/ds_call_provider.enum.dart b/lib/src/enums/ds_call_provider.enum.dart index c20790b7..c5f3dbd7 100644 --- a/lib/src/enums/ds_call_provider.enum.dart +++ b/lib/src/enums/ds_call_provider.enum.dart @@ -1,4 +1,5 @@ enum DSCallProvider { mobcall, - whatsapp, + whatsApp, + unknown, } diff --git a/lib/src/enums/ds_call_status.enum.dart b/lib/src/enums/ds_call_status.enum.dart new file mode 100644 index 00000000..291e9816 --- /dev/null +++ b/lib/src/enums/ds_call_status.enum.dart @@ -0,0 +1,6 @@ +enum DSCallStatus { + completed, + answer, + noAnswer, + unknown, +} diff --git a/lib/src/enums/ds_call_type.enum.dart b/lib/src/enums/ds_call_type.enum.dart index f0c5d1df..779633e5 100644 --- a/lib/src/enums/ds_call_type.enum.dart +++ b/lib/src/enums/ds_call_type.enum.dart @@ -1,4 +1,5 @@ enum DSCallType { voice, video, + unknown, } diff --git a/lib/src/extensions/ds_enum.extension.dart b/lib/src/extensions/ds_enum.extension.dart new file mode 100644 index 00000000..79cc969a --- /dev/null +++ b/lib/src/extensions/ds_enum.extension.dart @@ -0,0 +1,12 @@ +extension EnumByNameOrNull on Iterable { + T byNameOrDefault(String name, T defaultValue) { + for (var value in this) { + if (value.name.toString().toLowerCase() == + name.toString().toLowerCase()) { + return value; + } + } + + return defaultValue; + } +} diff --git a/lib/src/models/ds_calls_media_message.model.dart b/lib/src/models/ds_calls_media_message.model.dart index b59d6ab2..ca98f5d7 100644 --- a/lib/src/models/ds_calls_media_message.model.dart +++ b/lib/src/models/ds_calls_media_message.model.dart @@ -1,38 +1,49 @@ import '../enums/ds_call_direction.enum.dart'; import '../enums/ds_call_provider.enum.dart'; +import '../enums/ds_call_status.enum.dart'; import '../enums/ds_call_type.enum.dart'; +import '../extensions/ds_enum.extension.dart'; class DSCallsMediaMessage { - DSCallType? type; - String sessionId; - DSCallProvider? provider; - DSCallDirection direction; - String? ticketId; - String status; - String identification; - String? media; - int? callDuration; + final String sessionId; + final DSCallType type; + final DSCallProvider provider; + final DSCallDirection direction; + final DSCallStatus status; + final String ticketId; + final String identification; + final int? callDuration; DSCallsMediaMessage({ - this.type, required this.sessionId, - this.provider, + required this.type, + required this.provider, required this.direction, - this.ticketId, required this.status, + required this.ticketId, required this.identification, - this.media, this.callDuration, }); DSCallsMediaMessage.fromJson(Map json) - : type = json['type'], - sessionId = json['sessionId'], - provider = json['provider'], - direction = json['direction'], + : sessionId = json['sessionId'], + type = DSCallType.values.byNameOrDefault( + json['type'], + DSCallType.unknown, + ), + provider = DSCallProvider.values.byNameOrDefault( + json['provider'], + DSCallProvider.unknown, + ), + direction = DSCallDirection.values.byNameOrDefault( + json['direction'], + DSCallDirection.unknown, + ), + status = DSCallStatus.values.byNameOrDefault( + json['status'], + DSCallStatus.unknown, + ), ticketId = json['ticketId'], - status = json['status'], identification = json['identification'], - media = json['media'], - callDuration = json['callDuration']; + callDuration = json['callDuration'] ?? 0; } diff --git a/lib/src/widgets/chat/calls/ds_end_calls_message_bubble.widget.dart b/lib/src/widgets/chat/calls/ds_end_calls_message_bubble.widget.dart new file mode 100644 index 00000000..d9c7aa11 --- /dev/null +++ b/lib/src/widgets/chat/calls/ds_end_calls_message_bubble.widget.dart @@ -0,0 +1,276 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import '../../../enums/ds_align.enum.dart'; +import '../../../enums/ds_border_radius.enum.dart'; +import '../../../enums/ds_call_direction.enum.dart'; +import '../../../enums/ds_call_status.enum.dart'; +import '../../../extensions/ds_localization.extension.dart'; +import '../../../extensions/ds_string.extension.dart'; +import '../../../models/ds_calls_media_message.model.dart'; +import '../../../models/ds_message_bubble_style.model.dart'; +import '../../../themes/colors/ds_colors.theme.dart'; +import '../../../themes/icons/ds_icons.dart'; +import '../../../themes/texts/utils/ds_font_weights.theme.dart'; +import '../../animations/ds_spinner_loading.widget.dart'; +import '../../buttons/ds_button.widget.dart'; +import '../../texts/ds_caption_small_text.widget.dart'; +import '../../texts/ds_caption_text.widget.dart'; +import '../../texts/ds_headline_small_text.widget.dart'; +import '../audio/ds_audio_player.widget.dart'; +import '../ds_message_bubble.widget.dart'; +import 'ds_end_calls_recording_container.widget.dart'; + +class DSEndCallsMessageBubble extends StatefulWidget { + final DSAlign align; + final List borderRadius; + final DSMessageBubbleStyle style; + final DSCallsMediaMessage callsMediaMessage; + final Future Function(String)? onAsyncFetchSession; + final Map? translations; + + DSEndCallsMessageBubble({ + super.key, + required this.align, + required this.callsMediaMessage, + required this.onAsyncFetchSession, + this.borderRadius = const [DSBorderRadius.all], + DSMessageBubbleStyle? style, + this.translations, + }) : style = style ?? DSMessageBubbleStyle(); + + @override + State createState() => + _DSEndCallsMessageBubbleState(); +} + +class _DSEndCallsMessageBubbleState extends State { + final StreamController _streamController = StreamController(); + late final Future _phoneNumber; + Future Function(String)? _onAsyncfetchsession; + + bool get _isCallAnswered => + [DSCallStatus.completed, DSCallStatus.answer].contains( + widget.callsMediaMessage.status, + ); + + bool get _isInbound => + widget.callsMediaMessage.direction == DSCallDirection.inbound; + + bool get _isLightBubbleBackground => + widget.style.isLightBubbleBackground(widget.align); + + bool get _isDefaultBubbleColors => + widget.style.isDefaultBubbleBackground(widget.align); + + Color get _foregroundColor => _isLightBubbleBackground + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow; + + @override + void initState() { + super.initState(); + _phoneNumber = + widget.callsMediaMessage.identification.toString().asPhoneNumber(); + _onAsyncfetchsession = widget.onAsyncFetchSession; + } + + @override + Widget build(BuildContext context) { + return DSMessageBubble( + padding: const EdgeInsets.symmetric( + vertical: 8.0, + horizontal: 10.0, + ), + borderRadius: widget.borderRadius, + align: widget.align, + style: widget.style, + child: Column( + children: [ + _buildCallInfo(), + _buildMediaPlayer(), + ], + ), + ); + } + + Widget _buildCallInfo() => Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.only(right: 8.0), + child: Container( + decoration: BoxDecoration( + color: _isCallAnswered ? DSColors.success : DSColors.error, + borderRadius: const BorderRadius.all( + Radius.circular( + 8.0, + ), + ), + ), + width: 40, + height: 40, + child: Icon( + _isCallAnswered + ? _isInbound + ? DSIcons.voip_receiving_outline + : DSIcons.voip_calling_outline + : DSIcons.voip_ended_outline, + size: 24.0, + ), + ), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DSHeadlineSmallText( + 'calls.voice-text'.translate(), + color: _foregroundColor, + ), + DSCaptionText( + _isCallAnswered + ? 'calls.answered'.translate() + : 'calls.unanswered'.translate(), + color: _foregroundColor, + fontWeight: DSFontWeights.semiBold, + ), + ], + ), + ], + ), + Flexible( + child: FutureBuilder( + future: _phoneNumber, + builder: (_, snapshot) { + if (snapshot.hasData && !snapshot.hasError) { + return DSCaptionSmallText( + snapshot.data, + color: _foregroundColor, + ); + } + return const DSSpinnerLoading(); + }, + ), + ), + ], + ); + + Widget _buildMediaPlayer() => _isCallAnswered && _onAsyncfetchsession != null + ? StreamBuilder( + stream: _streamController.stream, + builder: (_, __) { + return FutureBuilder( + future: _onAsyncfetchsession!( + widget.callsMediaMessage.sessionId, + ), + builder: (_, snapshot) { + return switch (snapshot.connectionState) { + ConnectionState.done => snapshot.hasError + ? _buildError() + : snapshot.data?.isEmpty ?? true + ? const SizedBox.shrink() + : _buildAudioPlayer(snapshot.data!), + _ => _buildLoading(), + }; + }, + ); + }, + ) + : const SizedBox.shrink(); + + Widget _buildAudioPlayer(final String data) => DSEndCallsRecordingContainer( + isLighBubbleBackground: _isLightBubbleBackground, + child: Padding( + padding: const EdgeInsets.only(right: 8.0), + child: DSAudioPlayer( + uri: Uri.parse(data), + controlForegroundColor: _isLightBubbleBackground + ? DSColors.neutralDarkRooftop + : DSColors.neutralLightSnow, + labelColor: _isLightBubbleBackground + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow, + bufferActiveTrackColor: _isLightBubbleBackground + ? DSColors.neutralMediumWave + : DSColors.neutralMediumElephant, + bufferInactiveTrackColor: _isLightBubbleBackground + ? DSColors.neutralDarkRooftop + : DSColors.neutralLightBox, + sliderActiveTrackColor: _isLightBubbleBackground + ? DSColors.primaryNight + : DSColors.primaryLight, + sliderThumbColor: _isLightBubbleBackground + ? DSColors.neutralDarkRooftop + : DSColors.neutralLightSnow, + speedForegroundColor: _isLightBubbleBackground + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow, + speedBorderColor: _isLightBubbleBackground + ? _isDefaultBubbleColors + ? DSColors.neutralMediumSilver + : DSColors.neutralDarkCity + : _isDefaultBubbleColors + ? DSColors.disabledText + : DSColors.neutralLightSnow, + ), + ), + ); + + Widget _buildLoading() => DSEndCallsRecordingContainer( + isLighBubbleBackground: _isLightBubbleBackground, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + const DSSpinnerLoading(), + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: DSCaptionText( + 'calls.preparing-record'.translate(), + color: _foregroundColor, + fontWeight: DSFontWeights.semiBold, + ), + ), + ], + ), + ), + ); + + Widget _buildError() => DSEndCallsRecordingContainer( + isLighBubbleBackground: _isLightBubbleBackground, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + DSCaptionText( + 'calls.load-record'.translate(), + color: _foregroundColor, + fontWeight: DSFontWeights.semiBold, + ), + DSButton( + onPressed: () => _streamController.add(true), + borderColor: _isLightBubbleBackground + ? DSColors.neutralMediumSilver + : DSColors.disabledText, + foregroundColor: _isLightBubbleBackground + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow, + backgroundColor: _isLightBubbleBackground + ? DSColors.neutralLightWhisper + : DSColors.neutralDarkDesk, + trailingIcon: const Icon( + DSIcons.refresh_outline, + size: 24.0, + ), + autoSize: true, + ) + ], + ), + ), + ); +} diff --git a/lib/src/widgets/chat/calls/ds_end_calls_recording_container.widget.dart b/lib/src/widgets/chat/calls/ds_end_calls_recording_container.widget.dart new file mode 100644 index 00000000..59c93fc1 --- /dev/null +++ b/lib/src/widgets/chat/calls/ds_end_calls_recording_container.widget.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; + +import '../../../themes/colors/ds_colors.theme.dart'; + +class DSEndCallsRecordingContainer extends StatelessWidget { + final bool isLighBubbleBackground; + final Widget child; + + const DSEndCallsRecordingContainer({ + super.key, + required this.isLighBubbleBackground, + required this.child, + }); + + @override + Widget build(BuildContext context) => SizedBox( + height: 60.0, + child: Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Container( + decoration: BoxDecoration( + color: isLighBubbleBackground + ? DSColors.neutralLightWhisper + : DSColors.neutralDarkDesk, + borderRadius: const BorderRadius.all( + Radius.circular( + 8.0, + ), + ), + ), + child: child, + ), + ), + ); +} diff --git a/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart b/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart deleted file mode 100644 index c72cf9ec..00000000 --- a/lib/src/widgets/chat/ds_end_calls_message_bubble.widget.dart +++ /dev/null @@ -1,258 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; - -import '../../../blip_ds.dart'; -import '../../extensions/ds_localization.extension.dart'; -import '../../models/ds_calls_media_message.model.dart'; - -class DSEndCallsMessageBubble extends StatelessWidget { - final DSAlign align; - final List borderRadius; - final DSMessageBubbleStyle style; - final DSCallsMediaMessage content; - final Future Function(String)? onAsyncFetchSession; - final StreamController _streamController = StreamController(); - final Map? translations; - - bool get _isCallAnswered => ['completed', 'answer'].contains( - content.status.toString().toLowerCase(), - ); - - bool get _isInbound => - content.direction.toString().toLowerCase() == 'inbound'; - - bool get _isLightBubbleBackground => style.isLightBubbleBackground(align); - bool get _isDefaultBubbleColors => style.isDefaultBubbleBackground(align); - - Color get _foregroundColor => _isLightBubbleBackground - ? DSColors.neutralDarkCity - : DSColors.neutralLightSnow; - - DSEndCallsMessageBubble({ - super.key, - required this.align, - required this.content, - required this.onAsyncFetchSession, - this.borderRadius = const [DSBorderRadius.all], - DSMessageBubbleStyle? style, - this.translations, - }) : style = style ?? DSMessageBubbleStyle(); - - @override - Widget build(BuildContext context) { - return DSMessageBubble( - borderRadius: borderRadius, - align: align, - style: style, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Column( - children: [ - Row( - children: [ - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: Container( - decoration: BoxDecoration( - color: _isCallAnswered - ? DSColors.success - : DSColors.error, - borderRadius: const BorderRadius.all( - Radius.circular( - 8.0, - ), - ), - ), - width: 40, - height: 40, - child: Icon( - _isCallAnswered - ? _isInbound - ? DSIcons.voip_receiving_outline - : DSIcons.voip_calling_outline - : DSIcons.voip_ended_outline, - size: 24.0, - ), - ), - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - DSHeadlineSmallText( - 'calls.voice-text'.translate(), - color: _foregroundColor, - ), - DSCaptionSmallText( - _isCallAnswered - ? 'calls.answered'.translate() - : 'calls.unanswered'.translate(), - color: _foregroundColor, - ), - ], - ), - ], - ), - ], - ), - Flexible( - child: Column( - children: [ - FutureBuilder( - future: content.identification.toString().asPhoneNumber(), - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - return DSCaptionSmallText( - snapshot.data, - color: _foregroundColor, - ); - } - return const DSSpinnerLoading(); - }, - ) - ], - ), - ), - ], - ), - if (_isCallAnswered && onAsyncFetchSession != null) - StreamBuilder( - stream: _streamController.stream, - builder: (_, __) { - return FutureBuilder( - future: onAsyncFetchSession!( - content.sessionId, - ), - builder: (_, snapshot) { - return switch (snapshot.connectionState) { - ConnectionState.waiting => _buildLoading(), - ConnectionState.done => snapshot.hasError - ? _buildError() - : snapshot.data?.isEmpty ?? true - ? const SizedBox.shrink() - : _buildAudioPlayer(snapshot.data!), - _ => const SizedBox.shrink(), - }; - }, - ); - }, - ) - ], - ), - ); - } - - Widget _buildContainer(final Widget child) => SizedBox( - height: 60.0, - child: Padding( - padding: const EdgeInsets.only(top: 8.0), - child: Container( - decoration: BoxDecoration( - color: _isLightBubbleBackground - ? DSColors.neutralLightWhisper - : DSColors.neutralDarkDesk, - borderRadius: const BorderRadius.all( - Radius.circular( - 8.0, - ), - ), - ), - child: child, - ), - ), - ); - - Widget _buildAudioPlayer(final String data) => _buildContainer( - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: DSAudioPlayer( - uri: Uri.parse(data), - controlForegroundColor: _isLightBubbleBackground - ? DSColors.neutralDarkRooftop - : DSColors.neutralLightSnow, - labelColor: _isLightBubbleBackground - ? DSColors.neutralDarkCity - : DSColors.neutralLightSnow, - bufferActiveTrackColor: _isLightBubbleBackground - ? DSColors.neutralMediumWave - : DSColors.neutralMediumElephant, - bufferInactiveTrackColor: _isLightBubbleBackground - ? DSColors.neutralDarkRooftop - : DSColors.neutralLightBox, - sliderActiveTrackColor: _isLightBubbleBackground - ? DSColors.primaryNight - : DSColors.primaryLight, - sliderThumbColor: _isLightBubbleBackground - ? DSColors.neutralDarkRooftop - : DSColors.neutralLightSnow, - speedForegroundColor: _isLightBubbleBackground - ? DSColors.neutralDarkCity - : DSColors.neutralLightSnow, - speedBorderColor: _isLightBubbleBackground - ? _isDefaultBubbleColors - ? DSColors.neutralMediumSilver - : DSColors.neutralDarkCity - : _isDefaultBubbleColors - ? DSColors.disabledText - : DSColors.neutralLightSnow, - ), - ), - ); - - Widget _buildLoading() => _buildContainer( - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - children: [ - const DSSpinnerLoading(), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: DSCaptionText( - 'calls.preparing-record'.translate(), - color: _foregroundColor, - fontWeight: DSFontWeights.semiBold, - ), - ), - ], - ), - ), - ); - - Widget _buildError() => _buildContainer( - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - DSCaptionText( - 'calls.load-record'.translate(), - color: _foregroundColor, - fontWeight: DSFontWeights.semiBold, - ), - DSButton( - onPressed: () => _streamController.add(true), - borderColor: _isLightBubbleBackground - ? DSColors.neutralMediumSilver - : DSColors.disabledText, - foregroundColor: _isLightBubbleBackground - ? DSColors.neutralDarkCity - : DSColors.neutralLightSnow, - backgroundColor: _isLightBubbleBackground - ? DSColors.neutralLightWhisper - : DSColors.neutralDarkDesk, - trailingIcon: const Icon( - DSIcons.refresh_outline, - size: 24.0, - ), - autoSize: true, - ) - ], - ), - ), - ); -} diff --git a/lib/src/widgets/utils/ds_card.widget.dart b/lib/src/widgets/utils/ds_card.widget.dart index 9a6acc35..f823f30b 100644 --- a/lib/src/widgets/utils/ds_card.widget.dart +++ b/lib/src/widgets/utils/ds_card.widget.dart @@ -6,6 +6,7 @@ import '../../enums/ds_align.enum.dart'; import '../../enums/ds_border_radius.enum.dart'; import '../../enums/ds_delivery_report_status.enum.dart'; import '../../enums/ds_ticket_message_type.enum.dart'; +import '../../models/ds_calls_media_message.model.dart'; import '../../models/ds_document_select.model.dart'; import '../../models/ds_media_link.model.dart'; import '../../models/ds_message_bubble_avatar_config.model.dart'; @@ -15,10 +16,10 @@ import '../../services/ds_file.service.dart'; import '../../utils/ds_message_content_type.util.dart'; import '../../utils/ds_utils.util.dart'; import '../chat/audio/ds_audio_message_bubble.widget.dart'; +import '../chat/calls/ds_end_calls_message_bubble.widget.dart'; import '../chat/ds_application_json_message_bubble.widget.dart'; import '../chat/ds_carrousel.widget.dart'; import '../chat/ds_contact_message_bubble.widget.dart'; -import '../chat/ds_end_calls_message_bubble.widget.dart'; import '../chat/ds_file_message_bubble.widget.dart'; import '../chat/ds_image_message_bubble.widget.dart'; import '../chat/ds_location_message_bubble.widget.dart'; @@ -175,7 +176,7 @@ class DSCard extends StatelessWidget { align: align, borderRadius: borderRadius, style: style, - content: content, + callsMediaMessage: DSCallsMediaMessage.fromJson(content), onAsyncFetchSession: onAsyncFetchSession, ); diff --git a/sample/assets/ds_localization.json b/sample/assets/ds_localization.json new file mode 100644 index 00000000..73c0f364 --- /dev/null +++ b/sample/assets/ds_localization.json @@ -0,0 +1,24 @@ +{ + "pt_BR": { + "calls.answered": "Finalizada", + "calls.unanswered": "Não atendida", + "calls.voice-text": "Ligação", + "calls.preparing-record": "Preparando gravação...", + "calls.load-record": "Carregar gravação" + + }, + "en_US": { + "calls.answered": "Ended", + "calls.unanswered": "Not answered", + "calls.voice-text": "Phone call", + "calls.preparing-record": "Preparing recording...", + "calls.load-record": "Load recording" + }, + "es_LA": { + "calls.answered": "Finalizada", + "calls.unanswered": "No atendida", + "calls.voice-text": "Llamada", + "calls.preparing-record": "Grabación en curso...", + "calls.load-record": "Cargar grabación" + } + } \ No newline at end of file diff --git a/sample/lib/main.dart b/sample/lib/main.dart index 08e63c52..0ac5f30f 100644 --- a/sample/lib/main.dart +++ b/sample/lib/main.dart @@ -1,5 +1,8 @@ +import 'dart:convert'; + import 'package:blip_ds/blip_ds.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:get/route_manager.dart'; import 'package:sample/widgets/showcase/sample_user_avatar.showcase.dart'; @@ -42,55 +45,77 @@ class SampleApp extends StatelessWidget { } } -class HomePage extends StatelessWidget { +class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); + @override + State createState() => _HomePageState(); +} + +class _HomePageState extends State { + late final Future _translations; + + @override + void initState() { + super.initState(); + _translations = rootBundle.loadString('assets/ds_localization.json'); + } + @override Widget build(BuildContext context) { return Scaffold( appBar: DSHeader( title: 'Blip Design System Showcase', ), - body: SafeArea( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: ListView( - children: [ - const SampleUserAvatarShowcase(), - SampleMessageBubbleShowcase(), - const Divider(color: DSColors.neutralDarkCity), - const SampleTextStyleShowcase(), - const Divider(color: DSColors.neutralDarkCity), - const SampleButtonShowcase(), - const Divider(color: DSColors.neutralDarkCity), - const SampleTypingShowcase(), - const Divider(color: DSColors.neutralDarkCity), - const SampleSwitchShowcase(), - const Divider(color: DSColors.neutralDarkCity), - const SampleDialogShowcase(), - const Divider(color: DSColors.neutralDarkCity), - const SampleToastShowcase(), - const Divider(color: DSColors.neutralDarkCity), - SampleRadioShowcase(), - const Divider(color: DSColors.neutralDarkCity), - SampleGroupCardShowcase(), - const Divider(color: DSColors.neutralDarkCity), - const SampleHeaderShowcase(), - const Divider(color: DSColors.neutralDarkCity), - const SampleBottomSheetShowcase(), - const Divider(color: DSColors.neutralDarkCity), - const SampleTicketMessage(), - const Divider(color: DSColors.neutralDarkCity), - const SampleCollectionShowcase(), - const Divider(color: DSColors.neutralDarkCity), - const SampleWeblinkShowcase(), - const Divider(color: DSColors.neutralDarkCity), - SampleInputShowcase(), - const Divider(color: DSColors.neutralDarkCity), - ], - ), - ), - ), + body: FutureBuilder( + future: _translations, + builder: (_, snapshot) { + if (snapshot.hasData) { + DSLocalizationService.setTranslations(jsonDecode(snapshot.data!)); + DSLocalizationService.setLocale(const Locale('pt', 'BR')); + } + + return SafeArea( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: ListView( + children: [ + const SampleUserAvatarShowcase(), + SampleMessageBubbleShowcase(), + const Divider(color: DSColors.neutralDarkCity), + const SampleTextStyleShowcase(), + const Divider(color: DSColors.neutralDarkCity), + const SampleButtonShowcase(), + const Divider(color: DSColors.neutralDarkCity), + const SampleTypingShowcase(), + const Divider(color: DSColors.neutralDarkCity), + const SampleSwitchShowcase(), + const Divider(color: DSColors.neutralDarkCity), + const SampleDialogShowcase(), + const Divider(color: DSColors.neutralDarkCity), + const SampleToastShowcase(), + const Divider(color: DSColors.neutralDarkCity), + SampleRadioShowcase(), + const Divider(color: DSColors.neutralDarkCity), + SampleGroupCardShowcase(), + const Divider(color: DSColors.neutralDarkCity), + const SampleHeaderShowcase(), + const Divider(color: DSColors.neutralDarkCity), + const SampleBottomSheetShowcase(), + const Divider(color: DSColors.neutralDarkCity), + const SampleTicketMessage(), + const Divider(color: DSColors.neutralDarkCity), + const SampleCollectionShowcase(), + const Divider(color: DSColors.neutralDarkCity), + const SampleWeblinkShowcase(), + const Divider(color: DSColors.neutralDarkCity), + SampleInputShowcase(), + const Divider(color: DSColors.neutralDarkCity), + ], + ), + ), + ); + }), ); } } diff --git a/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart b/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart index c1654ceb..84b714ee 100644 --- a/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart +++ b/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart @@ -17,7 +17,7 @@ class SampleMessageBubbleShowcase extends StatelessWidget { final RxString _sampleText = RxString(''); final String _sampleAudio = - 'https://s3.amazonaws.com/scifri-episodes/scifri20181123-episode.mp3'; + 'https://filesamples.com/samples/video/webm/sample_640x360.webm'; final Map _sampleImages = { "extraSmall": 'https://cdn-icons-png.flaticon.com/128/6913/6913220.png', @@ -48,15 +48,46 @@ class SampleMessageBubbleShowcase extends StatelessWidget { SampleMessageBubbleShowcase({Key? key}) : super(key: key); + Future _onAsyncFetchSession(_) { + return Future.delayed( + const Duration(seconds: 2), + () => _sampleAudio, + ); + } + + final _callsMediaMessage = { + "sessionId": "346b4783-2c8e-4b08-a71f-01904a3c40f3", + "type": "voice", + "provider": "whatsapp", + "direction": "inbound", + "status": "completed", + "ticketId": "ticketId", + "identification": "5548999999999", + "callDuration": 60, + }; + @override Widget build(BuildContext context) { return Obx( () => Column( children: [ DSEndCallsMessageBubble( - content: const {'identification': '55996226444'}, - onAsyncFetchSession: null, - align: DSAlign.left, + callsMediaMessage: DSCallsMediaMessage.fromJson(_callsMediaMessage), + onAsyncFetchSession: _onAsyncFetchSession, + align: DSAlign.right, + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: DSEndCallsMessageBubble( + callsMediaMessage: DSCallsMediaMessage.fromJson( + _callsMediaMessage + ..addAll( + {"callDuration": 0, "status": "noanswer"}, + ), + ), + onAsyncFetchSession: null, + align: DSAlign.right, + ), ), DSTextMessageBubble( text: 'Essa foto é linda', diff --git a/sample/pubspec.lock b/sample/pubspec.lock index b6377af1..137f897a 100644 --- a/sample/pubspec.lock +++ b/sample/pubspec.lock @@ -31,7 +31,7 @@ packages: path: ".." relative: true source: path - version: "0.1.4" + version: "0.1.5" boolean_selector: dependency: transitive description: diff --git a/sample/pubspec.yaml b/sample/pubspec.yaml index d0cd688d..a79aeb11 100644 --- a/sample/pubspec.yaml +++ b/sample/pubspec.yaml @@ -56,6 +56,7 @@ dev_dependencies: flutter: assets: - assets/messages.json + - assets/ds_localization.json # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in From d8277a13a1acd2097fc9e06e0291422cd31a18ff Mon Sep 17 00:00:00 2001 From: Andre Rossi Date: Tue, 20 Aug 2024 11:43:12 -0300 Subject: [PATCH 09/20] test: update golden image --- .../ds_pause_button/ds_pause_button.png | Bin 13446 -> 13454 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/test/widgets/buttons/goldens/ds_pause_button/ds_pause_button.png b/test/widgets/buttons/goldens/ds_pause_button/ds_pause_button.png index a18b171c15481cf185c0804b3a164dfc572441c7..020604f613b13dded9e2fff1ccf604f6d5f6297f 100644 GIT binary patch literal 13454 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 P5(ac_$#&R+jlwC0d2 literal 13446 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 b`;NXe|LiB4Cj75C82nM&?~9I{`}yAhWAAdX From 20f5e909fd14304d68535da1596552e854d74af2 Mon Sep 17 00:00:00 2001 From: Andre Rossi Date: Tue, 20 Aug 2024 11:47:31 -0300 Subject: [PATCH 10/20] chore: change flutter version --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8c0dddba..1238338c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2 with: - flutter-version: '3.13.9' + flutter-version: '3.13.3' channel: 'stable' - name: Install dependencies run: flutter pub get From 3f45952cb22ea31161124f9fe906d6439d9e5fc4 Mon Sep 17 00:00:00 2001 From: Andre Rossi Date: Tue, 20 Aug 2024 11:57:40 -0300 Subject: [PATCH 11/20] test: revert flutter version --- .github/workflows/tests.yml | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1238338c..8c0dddba 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2 with: - flutter-version: '3.13.3' + flutter-version: '3.13.9' channel: 'stable' - name: Install dependencies run: flutter pub get diff --git a/pubspec.yaml b/pubspec.yaml index 7f464bf7..6a554a6f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: rxdart: ^0.27.4 flutter_spinkit: ^5.1.0 get: ^4.6.5 - open_filex: ^4.3.2 + open_filex: 4.3.2 path_provider: ^2.1.1 dio: ^5.2.1+1 url_launcher: ^6.1.5 From 5306558b89c5e2e9315e13a0a19abf87455de2d6 Mon Sep 17 00:00:00 2001 From: Andre Rossi Date: Tue, 20 Aug 2024 12:03:16 -0300 Subject: [PATCH 12/20] chore: change flutter version --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8c0dddba..1238338c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2 with: - flutter-version: '3.13.9' + flutter-version: '3.13.3' channel: 'stable' - name: Install dependencies run: flutter pub get From 82ab5bf8b51eec78cc30c9c6621cfe052345f1e5 Mon Sep 17 00:00:00 2001 From: adrianoct42 Date: Wed, 21 Aug 2024 17:26:40 -0300 Subject: [PATCH 13/20] fix: changed DSPrimaryButton and TertiaryButton parameters --- .github/workflows/tests.yml | 4 +-- .../buttons/ds_primary_button.widget.dart | 11 +++++--- .../buttons/ds_tertiary_button.widget.dart | 8 ++++-- .../ds_end_calls_message_bubble.widget.dart | 4 +-- .../sample_message_bubble.showcase.dart | 27 ++++++++++++++----- 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1238338c..d918d4b7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,8 +20,8 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2 with: - flutter-version: '3.13.3' - channel: 'stable' + flutter-version: "3.13.9" + channel: "stable" - name: Install dependencies run: flutter pub get - name: Run tests diff --git a/lib/src/widgets/buttons/ds_primary_button.widget.dart b/lib/src/widgets/buttons/ds_primary_button.widget.dart index d349632e..f14837e5 100644 --- a/lib/src/widgets/buttons/ds_primary_button.widget.dart +++ b/lib/src/widgets/buttons/ds_primary_button.widget.dart @@ -1,3 +1,5 @@ +import 'dart:ui'; + import '../../themes/colors/ds_colors.theme.dart'; import 'ds_button.widget.dart'; @@ -17,11 +19,14 @@ class DSPrimaryButton extends DSButton { super.isLoading, super.autoSize, super.contentAlignment, + Color? backgroundColor, + Color? foregroundColor, }) : super( - backgroundColor: - isEnabled ? DSColors.primaryNight : DSColors.disabledBg, + backgroundColor: isEnabled + ? backgroundColor ?? DSColors.primaryNight + : DSColors.disabledBg, foregroundColor: isEnabled - ? DSColors.neutralLightSnow + ? foregroundColor ?? DSColors.neutralLightSnow : DSColors.neutralMediumElephant, ); } diff --git a/lib/src/widgets/buttons/ds_tertiary_button.widget.dart b/lib/src/widgets/buttons/ds_tertiary_button.widget.dart index 800f2651..ef77dbd5 100644 --- a/lib/src/widgets/buttons/ds_tertiary_button.widget.dart +++ b/lib/src/widgets/buttons/ds_tertiary_button.widget.dart @@ -19,10 +19,14 @@ class DSTertiaryButton extends DSButton { super.isLoading, super.autoSize, super.contentAlignment, + Color? backgroundColor, + Color? foregroundColor, + Color? borderColor, }) : super( - backgroundColor: Colors.transparent, + backgroundColor: backgroundColor ?? Colors.transparent, foregroundColor: isEnabled - ? DSColors.neutralDarkCity + ? foregroundColor ?? DSColors.neutralDarkCity : DSColors.neutralMediumElephant, + borderColor: borderColor ?? DSColors.neutralLightSnow, ); } diff --git a/lib/src/widgets/chat/calls/ds_end_calls_message_bubble.widget.dart b/lib/src/widgets/chat/calls/ds_end_calls_message_bubble.widget.dart index d9c7aa11..32967b52 100644 --- a/lib/src/widgets/chat/calls/ds_end_calls_message_bubble.widget.dart +++ b/lib/src/widgets/chat/calls/ds_end_calls_message_bubble.widget.dart @@ -14,7 +14,7 @@ import '../../../themes/colors/ds_colors.theme.dart'; import '../../../themes/icons/ds_icons.dart'; import '../../../themes/texts/utils/ds_font_weights.theme.dart'; import '../../animations/ds_spinner_loading.widget.dart'; -import '../../buttons/ds_button.widget.dart'; +import '../../buttons/ds_tertiary_button.widget.dart'; import '../../texts/ds_caption_small_text.widget.dart'; import '../../texts/ds_caption_text.widget.dart'; import '../../texts/ds_headline_small_text.widget.dart'; @@ -252,7 +252,7 @@ class _DSEndCallsMessageBubbleState extends State { color: _foregroundColor, fontWeight: DSFontWeights.semiBold, ), - DSButton( + DSTertiaryButton( onPressed: () => _streamController.add(true), borderColor: _isLightBubbleBackground ? DSColors.neutralMediumSilver diff --git a/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart b/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart index 84b714ee..ef3e56f4 100644 --- a/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart +++ b/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart @@ -55,6 +55,13 @@ class SampleMessageBubbleShowcase extends StatelessWidget { ); } + Future _onAsyncFetchSessionError(_) { + return Future.delayed( + const Duration(seconds: 2), + () => throw UnimplementedError(), + ); + } + final _callsMediaMessage = { "sessionId": "346b4783-2c8e-4b08-a71f-01904a3c40f3", "type": "voice", @@ -79,16 +86,22 @@ class SampleMessageBubbleShowcase extends StatelessWidget { Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: DSEndCallsMessageBubble( - callsMediaMessage: DSCallsMediaMessage.fromJson( - _callsMediaMessage - ..addAll( - {"callDuration": 0, "status": "noanswer"}, - ), - ), - onAsyncFetchSession: null, + callsMediaMessage: + DSCallsMediaMessage.fromJson(_callsMediaMessage), + onAsyncFetchSession: _onAsyncFetchSessionError, align: DSAlign.right, ), ), + DSEndCallsMessageBubble( + callsMediaMessage: DSCallsMediaMessage.fromJson( + _callsMediaMessage + ..addAll( + {"callDuration": 0, "status": "noanswer"}, + ), + ), + onAsyncFetchSession: null, + align: DSAlign.right, + ), DSTextMessageBubble( text: 'Essa foto é linda', align: DSAlign.left, From cec51b8edb8ba67c999dafd32a14537b7798895b Mon Sep 17 00:00:00 2001 From: adrianoct42 Date: Thu, 22 Aug 2024 14:55:15 -0300 Subject: [PATCH 14/20] fix: tertiary button doesn't have default value now, DSEndCallsMessageBubble FutureBuilder refactoring --- .../widgets/buttons/ds_tertiary_button.widget.dart | 3 +-- .../calls/ds_end_calls_message_bubble.widget.dart | 12 ++++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/src/widgets/buttons/ds_tertiary_button.widget.dart b/lib/src/widgets/buttons/ds_tertiary_button.widget.dart index ef77dbd5..3406fb20 100644 --- a/lib/src/widgets/buttons/ds_tertiary_button.widget.dart +++ b/lib/src/widgets/buttons/ds_tertiary_button.widget.dart @@ -21,12 +21,11 @@ class DSTertiaryButton extends DSButton { super.contentAlignment, Color? backgroundColor, Color? foregroundColor, - Color? borderColor, + super.borderColor, }) : super( backgroundColor: backgroundColor ?? Colors.transparent, foregroundColor: isEnabled ? foregroundColor ?? DSColors.neutralDarkCity : DSColors.neutralMediumElephant, - borderColor: borderColor ?? DSColors.neutralLightSnow, ); } diff --git a/lib/src/widgets/chat/calls/ds_end_calls_message_bubble.widget.dart b/lib/src/widgets/chat/calls/ds_end_calls_message_bubble.widget.dart index 32967b52..c1117c82 100644 --- a/lib/src/widgets/chat/calls/ds_end_calls_message_bubble.widget.dart +++ b/lib/src/widgets/chat/calls/ds_end_calls_message_bubble.widget.dart @@ -48,7 +48,7 @@ class DSEndCallsMessageBubble extends StatefulWidget { class _DSEndCallsMessageBubbleState extends State { final StreamController _streamController = StreamController(); late final Future _phoneNumber; - Future Function(String)? _onAsyncfetchsession; + Future? _session; bool get _isCallAnswered => [DSCallStatus.completed, DSCallStatus.answer].contains( @@ -73,7 +73,9 @@ class _DSEndCallsMessageBubbleState extends State { super.initState(); _phoneNumber = widget.callsMediaMessage.identification.toString().asPhoneNumber(); - _onAsyncfetchsession = widget.onAsyncFetchSession; + _session = widget.onAsyncFetchSession?.call( + widget.callsMediaMessage.sessionId, + ); } @override @@ -159,14 +161,12 @@ class _DSEndCallsMessageBubbleState extends State { ], ); - Widget _buildMediaPlayer() => _isCallAnswered && _onAsyncfetchsession != null + Widget _buildMediaPlayer() => _isCallAnswered && _session != null ? StreamBuilder( stream: _streamController.stream, builder: (_, __) { return FutureBuilder( - future: _onAsyncfetchsession!( - widget.callsMediaMessage.sessionId, - ), + future: _session, builder: (_, snapshot) { return switch (snapshot.connectionState) { ConnectionState.done => snapshot.hasError From 4d52afa95b31ff2e8ecd30932608503d8dd3eb2a Mon Sep 17 00:00:00 2001 From: Marcelo Amaro Date: Thu, 22 Aug 2024 15:52:15 -0300 Subject: [PATCH 15/20] test: remove DSPauseButton golden --- .../goldens/ds_pause_button/ds_pause_button.png | Bin 13454 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 test/widgets/buttons/goldens/ds_pause_button/ds_pause_button.png diff --git a/test/widgets/buttons/goldens/ds_pause_button/ds_pause_button.png b/test/widgets/buttons/goldens/ds_pause_button/ds_pause_button.png deleted file mode 100644 index 020604f613b13dded9e2fff1ccf604f6d5f6297f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13454 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 P5(ac_$#&R+jlwC0d2 From 725c8495f2d3d24906047e43ad4aa379db63276e Mon Sep 17 00:00:00 2001 From: Marcelo Amaro Date: Thu, 22 Aug 2024 15:52:44 -0300 Subject: [PATCH 16/20] test: add DSPauseButton golden --- .../goldens/ds_pause_button/ds_pause_button.png | Bin 0 -> 13454 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/widgets/buttons/goldens/ds_pause_button/ds_pause_button.png diff --git a/test/widgets/buttons/goldens/ds_pause_button/ds_pause_button.png b/test/widgets/buttons/goldens/ds_pause_button/ds_pause_button.png new file mode 100644 index 0000000000000000000000000000000000000000..020604f613b13dded9e2fff1ccf604f6d5f6297f GIT binary patch literal 13454 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 P5(ac_$#&R+jlwC0d2 literal 0 HcmV?d00001 From 75788ee3a746daf076d4eaf5b972f537ae91dedd Mon Sep 17 00:00:00 2001 From: Marcelo Amaro Date: Thu, 22 Aug 2024 15:56:19 -0300 Subject: [PATCH 17/20] test: downgrade flutter version from 3.13.9 to 3.13.3 --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d918d4b7..bb9b55d1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2 with: - flutter-version: "3.13.9" + flutter-version: "3.13.3" channel: "stable" - name: Install dependencies run: flutter pub get From 2b1399825f50b420562a0abf83c90c03868710e4 Mon Sep 17 00:00:00 2001 From: Marcelo Amaro Date: Thu, 22 Aug 2024 16:01:45 -0300 Subject: [PATCH 18/20] test: update DSPauseButton golden --- .github/workflows/tests.yml | 2 +- .../ds_pause_button/ds_pause_button.png | Bin 13454 -> 16608 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bb9b55d1..d918d4b7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2 with: - flutter-version: "3.13.3" + flutter-version: "3.13.9" channel: "stable" - name: Install dependencies run: flutter pub get diff --git a/test/widgets/buttons/goldens/ds_pause_button/ds_pause_button.png b/test/widgets/buttons/goldens/ds_pause_button/ds_pause_button.png index 020604f613b13dded9e2fff1ccf604f6d5f6297f..e3cc12601c64a49b7ad7c8c8ba8803b570cdd921 100644 GIT binary patch literal 16608 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 X>Dj=@3Yh-u0@^nWu9sf3d;DJjVr$cS literal 13454 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 P5(ac_$#&R+jlwC0d2 From 3c8c8584e72a03ad799c77b60fe678e0fbb56532 Mon Sep 17 00:00:00 2001 From: Marcelo Amaro Date: Mon, 26 Aug 2024 08:32:34 -0300 Subject: [PATCH 19/20] feat: change end calls layout disposition --- lib/blip_ds.dart | 1 + lib/src/extensions/ds_enum.extension.dart | 6 +- .../models/ds_calls_media_message.model.dart | 34 +-- lib/src/themes/colors/ds_colors.theme.dart | 2 +- .../buttons/ds_ghost_button.widget.dart | 23 ++ .../buttons/ds_secondary_button.widget.dart | 21 +- .../buttons/ds_tertiary_button.widget.dart | 7 +- .../ds_end_calls_message_bubble.widget.dart | 198 ++++++++---------- ..._end_calls_recording_container.widget.dart | 27 ++- .../sample_message_bubble.showcase.dart | 39 +++- sample/pubspec.lock | 4 +- 11 files changed, 193 insertions(+), 169 deletions(-) create mode 100644 lib/src/widgets/buttons/ds_ghost_button.widget.dart diff --git a/lib/blip_ds.dart b/lib/blip_ds.dart index f359d86c..624125b6 100644 --- a/lib/blip_ds.dart +++ b/lib/blip_ds.dart @@ -114,6 +114,7 @@ export 'src/widgets/buttons/ds_attachment_button.widget.dart' export 'src/widgets/buttons/ds_button.widget.dart' show DSButton; export 'src/widgets/buttons/ds_custom_replies_icon_button.widget.dart' show DSCustomRepliesIconButton; +export 'src/widgets/buttons/ds_ghost_button.widget.dart' show DSGhostButton; export 'src/widgets/buttons/ds_icon_button.widget.dart' show DSIconButton; export 'src/widgets/buttons/ds_pause_button.widget.dart' show DSPauseButton; export 'src/widgets/buttons/ds_play_button.widget.dart' show DSPlayButton; diff --git a/lib/src/extensions/ds_enum.extension.dart b/lib/src/extensions/ds_enum.extension.dart index 79cc969a..18ce0d2b 100644 --- a/lib/src/extensions/ds_enum.extension.dart +++ b/lib/src/extensions/ds_enum.extension.dart @@ -1,12 +1,12 @@ extension EnumByNameOrNull on Iterable { - T byNameOrDefault(String name, T defaultValue) { + T? byNameOrNull(String? name) { for (var value in this) { if (value.name.toString().toLowerCase() == - name.toString().toLowerCase()) { + name?.toString().toLowerCase()) { return value; } } - return defaultValue; + return null; } } diff --git a/lib/src/models/ds_calls_media_message.model.dart b/lib/src/models/ds_calls_media_message.model.dart index ca98f5d7..8c6e1acd 100644 --- a/lib/src/models/ds_calls_media_message.model.dart +++ b/lib/src/models/ds_calls_media_message.model.dart @@ -5,13 +5,13 @@ import '../enums/ds_call_type.enum.dart'; import '../extensions/ds_enum.extension.dart'; class DSCallsMediaMessage { - final String sessionId; - final DSCallType type; - final DSCallProvider provider; - final DSCallDirection direction; - final DSCallStatus status; - final String ticketId; - final String identification; + final String? sessionId; + final DSCallType? type; + final DSCallProvider? provider; + final DSCallDirection? direction; + final DSCallStatus? status; + final String? ticketId; + final String? identification; final int? callDuration; DSCallsMediaMessage({ @@ -27,22 +27,10 @@ class DSCallsMediaMessage { DSCallsMediaMessage.fromJson(Map json) : sessionId = json['sessionId'], - type = DSCallType.values.byNameOrDefault( - json['type'], - DSCallType.unknown, - ), - provider = DSCallProvider.values.byNameOrDefault( - json['provider'], - DSCallProvider.unknown, - ), - direction = DSCallDirection.values.byNameOrDefault( - json['direction'], - DSCallDirection.unknown, - ), - status = DSCallStatus.values.byNameOrDefault( - json['status'], - DSCallStatus.unknown, - ), + type = DSCallType.values.byNameOrNull(json['type']), + provider = DSCallProvider.values.byNameOrNull(json['provider']), + direction = DSCallDirection.values.byNameOrNull(json['direction']), + status = DSCallStatus.values.byNameOrNull(json['status']), ticketId = json['ticketId'], identification = json['identification'], callDuration = json['callDuration'] ?? 0; diff --git a/lib/src/themes/colors/ds_colors.theme.dart b/lib/src/themes/colors/ds_colors.theme.dart index 4b045d80..257f8ac0 100644 --- a/lib/src/themes/colors/ds_colors.theme.dart +++ b/lib/src/themes/colors/ds_colors.theme.dart @@ -58,7 +58,7 @@ abstract class DSColors { static const Color disabledText = Color(0xFF637798); static const Color disabledBg = Color(0xFFE8F2FF); static const Color contentDisable = Color(0xFF636363); - static const Color border1 = Color(0xFF616161); + static const Color border1 = Color(0xFFC9C9C9); static Gradient gradientOcean = DSLinearGradient( colors: const [ diff --git a/lib/src/widgets/buttons/ds_ghost_button.widget.dart b/lib/src/widgets/buttons/ds_ghost_button.widget.dart new file mode 100644 index 00000000..c05cba52 --- /dev/null +++ b/lib/src/widgets/buttons/ds_ghost_button.widget.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; + +import '../../../blip_ds.dart'; + +/// A Design System's [ButtonStyleButton] primarily used by call to action. +class DSGhostButton extends DSSecondaryButton { + /// Creates a Design System's [ButtonStyleButton] with ghost style. + DSGhostButton({ + required super.onPressed, + super.key, + super.leadingIcon, + super.label, + super.trailingIcon, + super.isEnabled, + super.isLoading, + super.autoSize, + super.contentAlignment, + super.foregroundColor, + super.borderColor, + }) : super( + backgroundColor: Colors.transparent, + ); +} diff --git a/lib/src/widgets/buttons/ds_secondary_button.widget.dart b/lib/src/widgets/buttons/ds_secondary_button.widget.dart index 0ee61c58..4af637f3 100644 --- a/lib/src/widgets/buttons/ds_secondary_button.widget.dart +++ b/lib/src/widgets/buttons/ds_secondary_button.widget.dart @@ -1,3 +1,5 @@ +import 'package:flutter/material.dart'; + import '../../themes/colors/ds_colors.theme.dart'; import 'ds_button.widget.dart'; @@ -17,13 +19,18 @@ class DSSecondaryButton extends DSButton { super.isLoading, super.autoSize, super.contentAlignment, - super.backgroundColor = DSColors.neutralLightSnow, + Color? backgroundColor, + Color? foregroundColor, + Color? borderColor, }) : super( - foregroundColor: isEnabled - ? DSColors.primaryNight - : DSColors.neutralMediumElephant, - borderColor: isEnabled - ? DSColors.primaryNight - : DSColors.neutralMediumElephant, + backgroundColor: backgroundColor ?? DSColors.neutralLightSnow, + foregroundColor: foregroundColor ?? + (isEnabled + ? DSColors.primaryNight + : DSColors.neutralMediumElephant), + borderColor: borderColor ?? + (isEnabled + ? DSColors.primaryNight + : DSColors.neutralMediumElephant), ); } diff --git a/lib/src/widgets/buttons/ds_tertiary_button.widget.dart b/lib/src/widgets/buttons/ds_tertiary_button.widget.dart index 3406fb20..800f2651 100644 --- a/lib/src/widgets/buttons/ds_tertiary_button.widget.dart +++ b/lib/src/widgets/buttons/ds_tertiary_button.widget.dart @@ -19,13 +19,10 @@ class DSTertiaryButton extends DSButton { super.isLoading, super.autoSize, super.contentAlignment, - Color? backgroundColor, - Color? foregroundColor, - super.borderColor, }) : super( - backgroundColor: backgroundColor ?? Colors.transparent, + backgroundColor: Colors.transparent, foregroundColor: isEnabled - ? foregroundColor ?? DSColors.neutralDarkCity + ? DSColors.neutralDarkCity : DSColors.neutralMediumElephant, ); } diff --git a/lib/src/widgets/chat/calls/ds_end_calls_message_bubble.widget.dart b/lib/src/widgets/chat/calls/ds_end_calls_message_bubble.widget.dart index c1117c82..6e77d727 100644 --- a/lib/src/widgets/chat/calls/ds_end_calls_message_bubble.widget.dart +++ b/lib/src/widgets/chat/calls/ds_end_calls_message_bubble.widget.dart @@ -2,24 +2,10 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import '../../../enums/ds_align.enum.dart'; -import '../../../enums/ds_border_radius.enum.dart'; +import '../../../../blip_ds.dart'; import '../../../enums/ds_call_direction.enum.dart'; import '../../../enums/ds_call_status.enum.dart'; import '../../../extensions/ds_localization.extension.dart'; -import '../../../extensions/ds_string.extension.dart'; -import '../../../models/ds_calls_media_message.model.dart'; -import '../../../models/ds_message_bubble_style.model.dart'; -import '../../../themes/colors/ds_colors.theme.dart'; -import '../../../themes/icons/ds_icons.dart'; -import '../../../themes/texts/utils/ds_font_weights.theme.dart'; -import '../../animations/ds_spinner_loading.widget.dart'; -import '../../buttons/ds_tertiary_button.widget.dart'; -import '../../texts/ds_caption_small_text.widget.dart'; -import '../../texts/ds_caption_text.widget.dart'; -import '../../texts/ds_headline_small_text.widget.dart'; -import '../audio/ds_audio_player.widget.dart'; -import '../ds_message_bubble.widget.dart'; import 'ds_end_calls_recording_container.widget.dart'; class DSEndCallsMessageBubble extends StatefulWidget { @@ -71,19 +57,23 @@ class _DSEndCallsMessageBubbleState extends State { @override void initState() { super.initState(); + _phoneNumber = widget.callsMediaMessage.identification.toString().asPhoneNumber(); - _session = widget.onAsyncFetchSession?.call( - widget.callsMediaMessage.sessionId, - ); + + _session = widget.callsMediaMessage.sessionId != null + ? widget.onAsyncFetchSession?.call( + widget.callsMediaMessage.sessionId!, + ) + : Future.value(null); } @override Widget build(BuildContext context) { return DSMessageBubble( padding: const EdgeInsets.symmetric( - vertical: 8.0, - horizontal: 10.0, + vertical: 12.0, + horizontal: 12.0, ), borderRadius: widget.borderRadius, align: widget.align, @@ -165,18 +155,24 @@ class _DSEndCallsMessageBubbleState extends State { ? StreamBuilder( stream: _streamController.stream, builder: (_, __) { - return FutureBuilder( - future: _session, - builder: (_, snapshot) { - return switch (snapshot.connectionState) { - ConnectionState.done => snapshot.hasError - ? _buildError() - : snapshot.data?.isEmpty ?? true - ? const SizedBox.shrink() - : _buildAudioPlayer(snapshot.data!), - _ => _buildLoading(), - }; - }, + return Padding( + padding: const EdgeInsets.only( + top: 8.0, + ), + child: DSAnimatedSize( + child: FutureBuilder( + future: _session, + builder: (_, snapshot) { + return switch (snapshot.connectionState) { + ConnectionState.done => + snapshot.hasError || (snapshot.data?.isEmpty ?? true) + ? _buildError() + : _buildAudioPlayer(snapshot.data!), + _ => _buildLoading(), + }; + }, + ), + ), ); }, ) @@ -184,93 +180,81 @@ class _DSEndCallsMessageBubbleState extends State { Widget _buildAudioPlayer(final String data) => DSEndCallsRecordingContainer( isLighBubbleBackground: _isLightBubbleBackground, - child: Padding( - padding: const EdgeInsets.only(right: 8.0), - child: DSAudioPlayer( - uri: Uri.parse(data), - controlForegroundColor: _isLightBubbleBackground - ? DSColors.neutralDarkRooftop - : DSColors.neutralLightSnow, - labelColor: _isLightBubbleBackground - ? DSColors.neutralDarkCity - : DSColors.neutralLightSnow, - bufferActiveTrackColor: _isLightBubbleBackground - ? DSColors.neutralMediumWave - : DSColors.neutralMediumElephant, - bufferInactiveTrackColor: _isLightBubbleBackground - ? DSColors.neutralDarkRooftop - : DSColors.neutralLightBox, - sliderActiveTrackColor: _isLightBubbleBackground - ? DSColors.primaryNight - : DSColors.primaryLight, - sliderThumbColor: _isLightBubbleBackground - ? DSColors.neutralDarkRooftop - : DSColors.neutralLightSnow, - speedForegroundColor: _isLightBubbleBackground - ? DSColors.neutralDarkCity - : DSColors.neutralLightSnow, - speedBorderColor: _isLightBubbleBackground - ? _isDefaultBubbleColors - ? DSColors.neutralMediumSilver - : DSColors.neutralDarkCity - : _isDefaultBubbleColors - ? DSColors.disabledText - : DSColors.neutralLightSnow, - ), + child: DSAudioPlayer( + uri: Uri.parse(data), + controlForegroundColor: _isLightBubbleBackground + ? DSColors.neutralDarkRooftop + : DSColors.neutralLightSnow, + labelColor: _isLightBubbleBackground + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow, + bufferActiveTrackColor: _isLightBubbleBackground + ? DSColors.neutralMediumWave + : DSColors.neutralMediumElephant, + bufferInactiveTrackColor: _isLightBubbleBackground + ? DSColors.neutralDarkRooftop + : DSColors.neutralLightBox, + sliderActiveTrackColor: _isLightBubbleBackground + ? DSColors.primaryNight + : DSColors.primaryLight, + sliderThumbColor: _isLightBubbleBackground + ? DSColors.neutralDarkRooftop + : DSColors.neutralLightSnow, + speedForegroundColor: _isLightBubbleBackground + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow, + speedBorderColor: _isLightBubbleBackground + ? _isDefaultBubbleColors + ? DSColors.neutralMediumSilver + : DSColors.neutralDarkCity + : _isDefaultBubbleColors + ? DSColors.disabledText + : DSColors.neutralLightSnow, ), ); Widget _buildLoading() => DSEndCallsRecordingContainer( isLighBubbleBackground: _isLightBubbleBackground, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - children: [ - const DSSpinnerLoading(), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: DSCaptionText( - 'calls.preparing-record'.translate(), - color: _foregroundColor, - fontWeight: DSFontWeights.semiBold, - ), + child: Row( + children: [ + const DSSpinnerLoading(), + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: DSBodyText( + 'calls.preparing-record'.translate(), + color: _foregroundColor, + fontWeight: DSFontWeights.semiBold, ), - ], - ), + ), + ], ), ); Widget _buildError() => DSEndCallsRecordingContainer( isLighBubbleBackground: _isLightBubbleBackground, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - DSCaptionText( - 'calls.load-record'.translate(), - color: _foregroundColor, - fontWeight: DSFontWeights.semiBold, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + DSBodyText( + 'calls.load-record'.translate(), + color: _foregroundColor, + fontWeight: DSFontWeights.semiBold, + ), + DSGhostButton( + onPressed: () => _streamController.add(true), + borderColor: _isLightBubbleBackground + ? DSColors.neutralMediumSilver + : DSColors.disabledText, + foregroundColor: _isLightBubbleBackground + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow, + trailingIcon: const Icon( + DSIcons.refresh_outline, + size: 24.0, ), - DSTertiaryButton( - onPressed: () => _streamController.add(true), - borderColor: _isLightBubbleBackground - ? DSColors.neutralMediumSilver - : DSColors.disabledText, - foregroundColor: _isLightBubbleBackground - ? DSColors.neutralDarkCity - : DSColors.neutralLightSnow, - backgroundColor: _isLightBubbleBackground - ? DSColors.neutralLightWhisper - : DSColors.neutralDarkDesk, - trailingIcon: const Icon( - DSIcons.refresh_outline, - size: 24.0, - ), - autoSize: true, - ) - ], - ), + autoSize: true, + ) + ], ), ); } diff --git a/lib/src/widgets/chat/calls/ds_end_calls_recording_container.widget.dart b/lib/src/widgets/chat/calls/ds_end_calls_recording_container.widget.dart index 59c93fc1..8aa66566 100644 --- a/lib/src/widgets/chat/calls/ds_end_calls_recording_container.widget.dart +++ b/lib/src/widgets/chat/calls/ds_end_calls_recording_container.widget.dart @@ -13,23 +13,20 @@ class DSEndCallsRecordingContainer extends StatelessWidget { }); @override - Widget build(BuildContext context) => SizedBox( - height: 60.0, - child: Padding( - padding: const EdgeInsets.only(top: 8.0), - child: Container( - decoration: BoxDecoration( - color: isLighBubbleBackground - ? DSColors.neutralLightWhisper - : DSColors.neutralDarkDesk, - borderRadius: const BorderRadius.all( - Radius.circular( - 8.0, - ), - ), + Widget build(BuildContext context) => Container( + decoration: BoxDecoration( + color: isLighBubbleBackground + ? DSColors.neutralLightWhisper + : DSColors.neutralDarkDesk, + borderRadius: const BorderRadius.all( + Radius.circular( + 8.0, ), - child: child, ), ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: child, + ), ); } diff --git a/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart b/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart index ef3e56f4..786ebeab 100644 --- a/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart +++ b/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart @@ -73,6 +73,17 @@ class SampleMessageBubbleShowcase extends StatelessWidget { "callDuration": 60, }; + final _callsMediaMessageError = { + "sessionId": "346b4783-2c8e-4b08-a71f-01904a3c40f3", + "type": "voice", + "provider": "whatsapp", + "direction": "inbound", + "ticketId": "ticketId", + "identification": "5548999999999", + "callDuration": 0, + "status": "noanswer", + }; + @override Widget build(BuildContext context) { return Obx( @@ -93,15 +104,31 @@ class SampleMessageBubbleShowcase extends StatelessWidget { ), ), DSEndCallsMessageBubble( - callsMediaMessage: DSCallsMediaMessage.fromJson( - _callsMediaMessage - ..addAll( - {"callDuration": 0, "status": "noanswer"}, - ), - ), + callsMediaMessage: + DSCallsMediaMessage.fromJson(_callsMediaMessageError), onAsyncFetchSession: null, align: DSAlign.right, ), + DSEndCallsMessageBubble( + callsMediaMessage: DSCallsMediaMessage.fromJson(_callsMediaMessage), + onAsyncFetchSession: _onAsyncFetchSession, + align: DSAlign.left, + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: DSEndCallsMessageBubble( + callsMediaMessage: + DSCallsMediaMessage.fromJson(_callsMediaMessage), + onAsyncFetchSession: _onAsyncFetchSessionError, + align: DSAlign.left, + ), + ), + DSEndCallsMessageBubble( + callsMediaMessage: + DSCallsMediaMessage.fromJson(_callsMediaMessageError), + onAsyncFetchSession: null, + align: DSAlign.left, + ), DSTextMessageBubble( text: 'Essa foto é linda', align: DSAlign.left, diff --git a/sample/pubspec.lock b/sample/pubspec.lock index 137f897a..354fd22f 100644 --- a/sample/pubspec.lock +++ b/sample/pubspec.lock @@ -467,10 +467,10 @@ packages: dependency: transitive description: name: open_filex - sha256: "74e2280754cf8161e860746c3181db2c996d6c1909c7057b738ede4a469816b8" + sha256: "854aefd72dfd74219dc8c8d1767c34ec1eae64b8399a5be317bddb1ec2108915" url: "https://pub.dev" source: hosted - version: "4.4.0" + version: "4.3.2" package_info_plus: dependency: transitive description: From 68bbba4484736788508ee5a7a7e15d1a39b04f7c Mon Sep 17 00:00:00 2001 From: Marcelo Amaro Date: Mon, 26 Aug 2024 09:06:37 -0300 Subject: [PATCH 20/20] chore: upgrade package version from 0.1.5 to 0.1.6 --- CHANGELOG.md | 4 ++++ pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4dfebed..ade38500 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.6 + +- Added several widgets to support Blip Calls. + ## 0.1.5 - [DSDarkColors] Added new Dark theme colors. diff --git a/pubspec.yaml b/pubspec.yaml index 7f464bf7..4bd098b9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: blip_ds description: Blip Design System for Flutter. -version: 0.1.5 +version: 0.1.6 homepage: https://github.com/takenet/blip-ds-flutter#readme repository: https://github.com/takenet/blip-ds-flutter