diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5931b0fa..8c0dddba 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -9,6 +9,9 @@ on: pull_request: branches: [main, develop] + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + jobs: tests: name: Run Automated Tests @@ -17,6 +20,7 @@ jobs: - uses: actions/checkout@v3 - uses: subosito/flutter-action@v2 with: + flutter-version: '3.13.9' channel: 'stable' - name: Install dependencies run: flutter pub get diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c2eddb6..9b3d0a79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.88 + +- [DSApplicationJsonMessageBubble] Added support for interactive lists and buttons. + ## 0.0.87 - [DSCircularProgress] Added widget to build circular progress indicator. diff --git a/lib/blip_ds.dart b/lib/blip_ds.dart index c6723372..db10c997 100644 --- a/lib/blip_ds.dart +++ b/lib/blip_ds.dart @@ -6,6 +6,8 @@ export 'src/enums/ds_delivery_report_status.enum.dart' show DSDeliveryReportStatus; export 'src/enums/ds_input_container_shape.enum.dart' show DSInputContainerShape; +export 'src/enums/ds_interactive_message_header_type.enum.dart' + show DSInteractiveMessageHeaderType; export 'src/enums/ds_survey_scale.enum.dart' show DSSurveyScale; export 'src/enums/ds_survey_type.enum.dart' show DSSurveyType; export 'src/enums/ds_ticket_message_type.enum.dart' show DSTicketMessageType; @@ -18,8 +20,32 @@ export 'src/models/ds_message_bubble_avatar_config.model.dart' show DSMessageBubbleAvatarConfig; export 'src/models/ds_message_bubble_style.model.dart' show DSMessageBubbleStyle; -export 'src/models/ds_message_item.model.dart' show DSMessageItemModel; +export 'src/models/ds_message_item.model.dart' show DSMessageItem; export 'src/models/ds_toast_props.model.dart' show DSToastProps; +export 'src/models/interactive_message/ds_interactive_message.model.dart' + show DSInteractiveMessage; +export 'src/models/interactive_message/ds_interactive_message_action.model.dart' + show DSInteractiveMessageAction; +export 'src/models/interactive_message/ds_interactive_message_body.model.dart' + show DSInteractiveMessageBody; +export 'src/models/interactive_message/ds_interactive_message_button.model.dart' + show DSInteractiveMessageButton; +export 'src/models/interactive_message/ds_interactive_message_document.model.dart' + show DSInteractiveMessageDocument; +export 'src/models/interactive_message/ds_interactive_message_footer.model.dart' + show DSInteractiveMessageFooter; +export 'src/models/interactive_message/ds_interactive_message_header.model.dart' + show DSInteractiveMessageHeader; +export 'src/models/interactive_message/ds_interactive_message_image.model.dart' + show DSInteractiveMessageImage; +export 'src/models/interactive_message/ds_interactive_message_media.model.dart' + show DSInteractiveMessageMedia; +export 'src/models/interactive_message/ds_interactive_message_row.model.dart' + show DSInteractiveMessageRow; +export 'src/models/interactive_message/ds_interactive_message_section.model.dart' + show DSInteractiveMessageSection; +export 'src/models/interactive_message/ds_interactive_message_video.model.dart' + show DSInteractiveMessageVideo; 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; @@ -89,6 +115,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/ds_application_json_message_bubble.widget.dart' + show DSApplicationJsonMessageBubble; export 'src/widgets/chat/ds_carrousel.widget.dart' show DSCarrousel; export 'src/widgets/chat/ds_contact_message_bubble.widget.dart' show DSContactMessageBubble; @@ -98,6 +126,10 @@ export 'src/widgets/chat/ds_file_message_bubble.widget.dart' show DSFileMessageBubble; export 'src/widgets/chat/ds_image_message_bubble.widget.dart' show DSImageMessageBubble; +export 'src/widgets/chat/ds_interactive_button_message_bubble.widget.dart' + show DSInteractiveButtonMessageBubble; +export 'src/widgets/chat/ds_interactive_list_message_bubble.widget.dart' + show DSInteractiveListMessageBubble; export 'src/widgets/chat/ds_location_message_bubble.widget.dart' show DSLocationMessageBubble; export 'src/widgets/chat/ds_message_bubble.widget.dart' show DSMessageBubble; diff --git a/lib/src/enums/ds_interactive_message_header_type.enum.dart b/lib/src/enums/ds_interactive_message_header_type.enum.dart new file mode 100644 index 00000000..be2eab78 --- /dev/null +++ b/lib/src/enums/ds_interactive_message_header_type.enum.dart @@ -0,0 +1,6 @@ +enum DSInteractiveMessageHeaderType { + text, + document, + image, + video, +} diff --git a/lib/src/models/ds_message_item.model.dart b/lib/src/models/ds_message_item.model.dart index e4d01fcf..3070ce8e 100644 --- a/lib/src/models/ds_message_item.model.dart +++ b/lib/src/models/ds_message_item.model.dart @@ -2,7 +2,7 @@ import '../enums/ds_align.enum.dart'; import '../enums/ds_delivery_report_status.enum.dart'; /// A Design System message model used with [DSGroupCard] to display grouped bubble -class DSMessageItemModel { +class DSMessageItem { /// Identifier of message String? id; @@ -30,8 +30,8 @@ class DSMessageItemModel { /// Used to define if a message detail (typicament a messages date and time) should be displayed or not bool? hideMessageDetail; - /// Creates a new Design System's [DSMessageItemModel] model - DSMessageItemModel({ + /// Creates a new Design System's [DSMessageItem] model + DSMessageItem({ this.id, required this.date, required this.displayDate, @@ -43,8 +43,8 @@ class DSMessageItemModel { this.hideMessageDetail, }); - factory DSMessageItemModel.fromJson(Map json) { - final messageItem = DSMessageItemModel( + factory DSMessageItem.fromJson(Map json) { + final messageItem = DSMessageItem( id: json['id'], date: json['date'], displayDate: json['displayDate'], diff --git a/lib/src/models/ds_select_option.model.dart b/lib/src/models/ds_select_option.model.dart index e5ebdc07..1ee09cfd 100644 --- a/lib/src/models/ds_select_option.model.dart +++ b/lib/src/models/ds_select_option.model.dart @@ -1,19 +1,19 @@ /// A Design System select options model used with [DSSelectMenu], [DSQuickReply] to display a options menu -class DSSelectOptionModel { +class DSSelectOption { String text; int? order; String? type; dynamic value; - DSSelectOptionModel({ + DSSelectOption({ required this.text, this.order, this.type, this.value, }); - factory DSSelectOptionModel.fromJson(Map json) { - final option = DSSelectOptionModel( + factory DSSelectOption.fromJson(Map json) { + final option = DSSelectOption( text: json['text'], ); diff --git a/lib/src/models/interactive_message/ds_interactive_message.model.dart b/lib/src/models/interactive_message/ds_interactive_message.model.dart new file mode 100644 index 00000000..e7bdbf34 --- /dev/null +++ b/lib/src/models/interactive_message/ds_interactive_message.model.dart @@ -0,0 +1,39 @@ +import 'ds_interactive_message_action.model.dart'; +import 'ds_interactive_message_body.model.dart'; +import 'ds_interactive_message_footer.model.dart'; +import 'ds_interactive_message_header.model.dart'; + +class DSInteractiveMessage { + final DSInteractiveMessageHeader? header; + final DSInteractiveMessageBody? body; + final DSInteractiveMessageAction? action; + final DSInteractiveMessageFooter? footer; + + DSInteractiveMessage({ + this.header, + this.body, + this.action, + this.footer, + }); + + DSInteractiveMessage.fromJson(Map json) + : header = json['header'] != null + ? DSInteractiveMessageHeader.fromJson(json['header']) + : null, + body = json['body'] != null + ? DSInteractiveMessageBody.fromJson(json['body']) + : null, + action = json['action'] != null + ? DSInteractiveMessageAction.fromJson(json['action']) + : null, + footer = json['footer'] != null + ? DSInteractiveMessageFooter.fromJson(json['footer']) + : null; + + Map toJson() => { + 'header': header?.toJson(), + 'body': body?.toJson(), + 'action': action?.toJson(), + 'footer': footer?.toJson(), + }; +} diff --git a/lib/src/models/interactive_message/ds_interactive_message_action.model.dart b/lib/src/models/interactive_message/ds_interactive_message_action.model.dart new file mode 100644 index 00000000..63fb0447 --- /dev/null +++ b/lib/src/models/interactive_message/ds_interactive_message_action.model.dart @@ -0,0 +1,45 @@ +import 'ds_interactive_message_button.model.dart'; +import 'ds_interactive_message_section.model.dart'; + +class DSInteractiveMessageAction { + final String? button; + final List? buttons; + final List? sections; + + DSInteractiveMessageAction({ + this.button, + this.buttons, + this.sections, + }); + + DSInteractiveMessageAction.fromJson(Map json) + : button = json['button'], + buttons = json['buttons'] != null + ? List.from(json['buttons']) + .map( + (e) => DSInteractiveMessageButton.fromJson(e), + ) + .toList() + : null, + sections = json['sections'] != null + ? List.from(json['sections']) + .map( + (e) => DSInteractiveMessageSection.fromJson(e), + ) + .toList() + : null; + + Map toJson() => { + 'button': button, + 'buttons': buttons + ?.map( + (e) => e.toJson(), + ) + .toList(), + 'sections': sections + ?.map( + (e) => e.toJson(), + ) + .toList(), + }; +} diff --git a/lib/src/models/interactive_message/ds_interactive_message_body.model.dart b/lib/src/models/interactive_message/ds_interactive_message_body.model.dart new file mode 100644 index 00000000..0857d953 --- /dev/null +++ b/lib/src/models/interactive_message/ds_interactive_message_body.model.dart @@ -0,0 +1,14 @@ +class DSInteractiveMessageBody { + final String? text; + + DSInteractiveMessageBody({ + this.text, + }); + + DSInteractiveMessageBody.fromJson(Map json) + : text = json['text']; + + Map toJson() => { + 'text': text, + }; +} diff --git a/lib/src/models/interactive_message/ds_interactive_message_button.model.dart b/lib/src/models/interactive_message/ds_interactive_message_button.model.dart new file mode 100644 index 00000000..56721c8b --- /dev/null +++ b/lib/src/models/interactive_message/ds_interactive_message_button.model.dart @@ -0,0 +1,14 @@ +class DSInteractiveMessageButton { + final String? title; + + DSInteractiveMessageButton({ + this.title, + }); + + DSInteractiveMessageButton.fromJson(Map json) + : title = json['reply']?['title']; + + Map toJson() => { + 'title': title, + }; +} diff --git a/lib/src/models/interactive_message/ds_interactive_message_document.model.dart b/lib/src/models/interactive_message/ds_interactive_message_document.model.dart new file mode 100644 index 00000000..04f47902 --- /dev/null +++ b/lib/src/models/interactive_message/ds_interactive_message_document.model.dart @@ -0,0 +1,20 @@ +import 'ds_interactive_message_media.model.dart'; + +class DSInteractiveMessageDocument extends DSInteractiveMessageMedia { + final String? filename; + + DSInteractiveMessageDocument({ + super.link, + this.filename, + }); + + DSInteractiveMessageDocument.fromJson(Map json) + : filename = json['filename'], + super.fromJson(json); + + @override + Map toJson() => { + 'link': super.link, + 'filename': filename, + }; +} diff --git a/lib/src/models/interactive_message/ds_interactive_message_footer.model.dart b/lib/src/models/interactive_message/ds_interactive_message_footer.model.dart new file mode 100644 index 00000000..4618de2c --- /dev/null +++ b/lib/src/models/interactive_message/ds_interactive_message_footer.model.dart @@ -0,0 +1,14 @@ +class DSInteractiveMessageFooter { + final String? text; + + DSInteractiveMessageFooter({ + this.text, + }); + + DSInteractiveMessageFooter.fromJson(Map json) + : text = json['text']; + + Map toJson() => { + 'text': text, + }; +} diff --git a/lib/src/models/interactive_message/ds_interactive_message_header.model.dart b/lib/src/models/interactive_message/ds_interactive_message_header.model.dart new file mode 100644 index 00000000..1b687336 --- /dev/null +++ b/lib/src/models/interactive_message/ds_interactive_message_header.model.dart @@ -0,0 +1,45 @@ +import 'package:get/get.dart'; + +import '../../enums/ds_interactive_message_header_type.enum.dart'; +import 'ds_interactive_message_document.model.dart'; +import 'ds_interactive_message_image.model.dart'; +import 'ds_interactive_message_video.model.dart'; + +class DSInteractiveMessageHeader { + final DSInteractiveMessageHeaderType? type; + final String? text; + final DSInteractiveMessageDocument? document; + final DSInteractiveMessageImage? image; + final DSInteractiveMessageVideo? video; + + DSInteractiveMessageHeader({ + this.type, + this.text, + this.document, + this.image, + this.video, + }); + + DSInteractiveMessageHeader.fromJson(Map json) + : type = DSInteractiveMessageHeaderType.values.firstWhereOrNull( + (e) => e.name == json['type'], + ), + text = json['text'], + document = json['document'] != null + ? DSInteractiveMessageDocument.fromJson(json['document']) + : null, + image = json['image'] != null + ? DSInteractiveMessageImage.fromJson(json['image']) + : null, + video = json['video'] != null + ? DSInteractiveMessageVideo.fromJson(json['video']) + : null; + + Map toJson() => { + 'type': type?.name, + 'text': text, + 'document': document?.toJson(), + 'image': image?.toJson(), + 'video': video?.toJson(), + }; +} diff --git a/lib/src/models/interactive_message/ds_interactive_message_image.model.dart b/lib/src/models/interactive_message/ds_interactive_message_image.model.dart new file mode 100644 index 00000000..d54d9415 --- /dev/null +++ b/lib/src/models/interactive_message/ds_interactive_message_image.model.dart @@ -0,0 +1,6 @@ +import 'ds_interactive_message_media.model.dart'; + +class DSInteractiveMessageImage extends DSInteractiveMessageMedia { + DSInteractiveMessageImage.fromJson(Map json) + : super.fromJson(json); +} diff --git a/lib/src/models/interactive_message/ds_interactive_message_media.model.dart b/lib/src/models/interactive_message/ds_interactive_message_media.model.dart new file mode 100644 index 00000000..931730e4 --- /dev/null +++ b/lib/src/models/interactive_message/ds_interactive_message_media.model.dart @@ -0,0 +1,14 @@ +abstract class DSInteractiveMessageMedia { + final String? link; + + DSInteractiveMessageMedia({ + this.link, + }); + + DSInteractiveMessageMedia.fromJson(Map json) + : link = json['link']; + + Map toJson() => { + 'link': link, + }; +} diff --git a/lib/src/models/interactive_message/ds_interactive_message_row.model.dart b/lib/src/models/interactive_message/ds_interactive_message_row.model.dart new file mode 100644 index 00000000..081c0bc9 --- /dev/null +++ b/lib/src/models/interactive_message/ds_interactive_message_row.model.dart @@ -0,0 +1,14 @@ +class DSInteractiveMessageRow { + final String? title; + + DSInteractiveMessageRow({ + this.title, + }); + + DSInteractiveMessageRow.fromJson(Map json) + : title = json['title']; + + Map toJson() => { + 'title': title, + }; +} diff --git a/lib/src/models/interactive_message/ds_interactive_message_section.model.dart b/lib/src/models/interactive_message/ds_interactive_message_section.model.dart new file mode 100644 index 00000000..df54d765 --- /dev/null +++ b/lib/src/models/interactive_message/ds_interactive_message_section.model.dart @@ -0,0 +1,30 @@ +import 'ds_interactive_message_row.model.dart'; + +class DSInteractiveMessageSection { + final String? title; + final List? rows; + + DSInteractiveMessageSection({ + this.title, + this.rows, + }); + + DSInteractiveMessageSection.fromJson(Map json) + : title = json['title'], + rows = json['rows'] != null + ? List.from(json['rows']) + .map( + (e) => DSInteractiveMessageRow.fromJson(e), + ) + .toList() + : null; + + Map toJson() => { + 'title': title, + 'rows': rows + ?.map( + (e) => e.toJson(), + ) + .toList(), + }; +} diff --git a/lib/src/models/interactive_message/ds_interactive_message_video.model.dart b/lib/src/models/interactive_message/ds_interactive_message_video.model.dart new file mode 100644 index 00000000..a1f10ab0 --- /dev/null +++ b/lib/src/models/interactive_message/ds_interactive_message_video.model.dart @@ -0,0 +1,6 @@ +import 'ds_interactive_message_media.model.dart'; + +class DSInteractiveMessageVideo extends DSInteractiveMessageMedia { + DSInteractiveMessageVideo.fromJson(Map json) + : super.fromJson(json); +} diff --git a/lib/src/widgets/buttons/ds_menu_item.widget.dart b/lib/src/widgets/buttons/ds_menu_item.widget.dart index cc5bb4be..d73f26d5 100644 --- a/lib/src/widgets/buttons/ds_menu_item.widget.dart +++ b/lib/src/widgets/buttons/ds_menu_item.widget.dart @@ -3,7 +3,8 @@ import 'package:flutter/material.dart'; import '../../enums/ds_align.enum.dart'; import '../../models/ds_message_bubble_style.model.dart'; import '../../themes/colors/ds_colors.theme.dart'; -import '../texts/ds_headline_small_text.widget.dart'; +import '../../themes/texts/utils/ds_font_weights.theme.dart'; +import '../texts/ds_body_text.widget.dart'; class DSMenuItem extends StatelessWidget { DSMenuItem({ @@ -12,6 +13,7 @@ class DSMenuItem extends StatelessWidget { required this.align, this.showBorder = false, this.onPressed, + this.fontWeight = DSFontWeights.bold, DSMessageBubbleStyle? style, }) : style = style ?? DSMessageBubbleStyle(), super(key: key) { @@ -24,6 +26,7 @@ class DSMenuItem extends StatelessWidget { final bool showBorder; final void Function()? onPressed; final DSMessageBubbleStyle style; + final FontWeight fontWeight; late final bool isDefaultBubbleColors; late final bool isLightBubbleBackground; @@ -55,8 +58,9 @@ class DSMenuItem extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Flexible( - child: DSHeadlineSmallText( + child: DSBodyText( text, + fontWeight: fontWeight, textAlign: TextAlign.center, color: isLightBubbleBackground ? isDefaultBubbleColors diff --git a/lib/src/widgets/chat/ds_application_json_bubble.widget.dart b/lib/src/widgets/chat/ds_application_json_bubble.widget.dart deleted file mode 100644 index 2463c596..00000000 --- a/lib/src/widgets/chat/ds_application_json_bubble.widget.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../enums/ds_align.enum.dart'; -import '../../enums/ds_border_radius.enum.dart'; -import '../../enums/ds_delivery_report_status.enum.dart'; -import '../../models/ds_message_bubble_style.model.dart'; -import '../../themes/colors/ds_colors.theme.dart'; -import '../../themes/icons/ds_icons.dart'; -import 'ds_unsupported_content_message_bubble.widget.dart'; - -class DSApplicationJsonMessageBubble extends StatelessWidget { - DSApplicationJsonMessageBubble({ - super.key, - required this.align, - required this.borderRadius, - required this.content, - this.status, - DSMessageBubbleStyle? style, - }) : style = style ?? DSMessageBubbleStyle(); - - final DSAlign align; - final List borderRadius; - final Map content; - final DSDeliveryReportStatus? status; - final DSMessageBubbleStyle style; - - @override - Widget build(BuildContext context) { - if (content['type'] == 'template') { - return Opacity( - opacity: status == DSDeliveryReportStatus.failed ? .3 : 1, - child: DSUnsupportedContentMessageBubble( - align: align, - borderRadius: borderRadius, - style: style, - overflow: TextOverflow.visible, - text: content['template']['name'], - leftWidget: Icon( - DSIcons.megaphone_outline, - color: style.isLightBubbleBackground(align) - ? DSColors.neutralDarkCity - : DSColors.neutralLightSnow, - size: 20.0, - ), - ), - ); - } - - return DSUnsupportedContentMessageBubble( - align: align, - borderRadius: borderRadius, - style: style, - ); - } -} diff --git a/lib/src/widgets/chat/ds_application_json_message_bubble.widget.dart b/lib/src/widgets/chat/ds_application_json_message_bubble.widget.dart new file mode 100644 index 00000000..7081c893 --- /dev/null +++ b/lib/src/widgets/chat/ds_application_json_message_bubble.widget.dart @@ -0,0 +1,89 @@ +import 'package:flutter/material.dart'; + +import '../../enums/ds_align.enum.dart'; +import '../../enums/ds_border_radius.enum.dart'; +import '../../enums/ds_delivery_report_status.enum.dart'; +import '../../models/ds_message_bubble_avatar_config.model.dart'; +import '../../models/ds_message_bubble_style.model.dart'; +import '../../models/interactive_message/ds_interactive_message.model.dart'; +import '../../themes/colors/ds_colors.theme.dart'; +import '../../themes/icons/ds_icons.dart'; +import 'ds_interactive_button_message_bubble.widget.dart'; +import 'ds_interactive_list_message_bubble.widget.dart'; +import 'ds_unsupported_content_message_bubble.widget.dart'; + +class DSApplicationJsonMessageBubble extends StatelessWidget { + DSApplicationJsonMessageBubble({ + super.key, + required this.align, + required this.borderRadius, + required this.content, + this.status, + this.avatarConfig = const DSMessageBubbleAvatarConfig(), + DSMessageBubbleStyle? style, + }) : style = style ?? DSMessageBubbleStyle(), + interactive = content['interactive'] ?? {}, + template = content['template'] ?? {}; + + final DSAlign align; + final List borderRadius; + final DSDeliveryReportStatus? status; + final DSMessageBubbleStyle style; + final DSMessageBubbleAvatarConfig avatarConfig; + + final Map content; + final Map interactive; + final Map template; + + @override + Widget build(BuildContext context) => switch (content['type']) { + 'template' => _buildTemplate(), + 'interactive' => _buildInteractive(), + _ => _buildUnsupportedContent(), + }; + + Widget _buildTemplate() => Opacity( + opacity: status == DSDeliveryReportStatus.failed ? .3 : 1, + child: DSUnsupportedContentMessageBubble( + align: align, + borderRadius: borderRadius, + style: style, + overflow: TextOverflow.visible, + text: template['name'], + leftWidget: Icon( + DSIcons.megaphone_outline, + color: style.isLightBubbleBackground(align) + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow, + size: 20.0, + ), + ), + ); + + Widget _buildInteractive() { + final content = DSInteractiveMessage.fromJson(interactive); + + return switch (interactive['type']) { + 'list' => DSInteractiveListMessageBubble( + content: content, + align: align, + borderRadius: borderRadius, + style: style, + ), + 'button' => DSInteractiveButtonMessageBubble( + content: content, + align: align, + borderRadius: borderRadius, + style: style, + avatarConfig: avatarConfig, + ), + _ => _buildUnsupportedContent(), + }; + } + + Widget _buildUnsupportedContent() => DSUnsupportedContentMessageBubble( + align: align, + borderRadius: borderRadius, + style: style, + ); +} diff --git a/lib/src/widgets/chat/ds_interactive_button_message_bubble.widget.dart b/lib/src/widgets/chat/ds_interactive_button_message_bubble.widget.dart new file mode 100644 index 00000000..4efc97cd --- /dev/null +++ b/lib/src/widgets/chat/ds_interactive_button_message_bubble.widget.dart @@ -0,0 +1,186 @@ +import 'package:flutter/material.dart'; + +import '../../enums/ds_align.enum.dart'; +import '../../enums/ds_border_radius.enum.dart'; +import '../../enums/ds_interactive_message_header_type.enum.dart'; +import '../../models/ds_message_bubble_avatar_config.model.dart'; +import '../../models/ds_message_bubble_style.model.dart'; +import '../../models/interactive_message/ds_interactive_message.model.dart'; +import '../../utils/ds_utils.util.dart'; +import '../buttons/ds_menu_item.widget.dart'; +import 'ds_file_message_bubble.widget.dart'; +import 'ds_image_message_bubble.widget.dart'; +import 'ds_message_bubble.widget.dart'; +import 'ds_text_message_bubble.widget.dart'; +import 'ds_unsupported_content_message_bubble.widget.dart'; +import 'video/ds_video_message_bubble.widget.dart'; + +class DSInteractiveButtonMessageBubble extends StatelessWidget { + final DSInteractiveMessage content; + final DSAlign align; + final List borderRadius; + final DSMessageBubbleAvatarConfig avatarConfig; + final DSMessageBubbleStyle style; + + late final bool isDefaultBubbleColors; + late final bool isLightBubbleBackground; + + final bool hasHeaderText; + final bool hasImageLink; + final bool hasVideoLink; + final bool hasDocumentLink; + final bool hasButtons; + + DSInteractiveButtonMessageBubble({ + super.key, + required this.content, + required this.align, + this.borderRadius = const [DSBorderRadius.all], + this.avatarConfig = const DSMessageBubbleAvatarConfig(), + DSMessageBubbleStyle? style, + }) : style = style ?? DSMessageBubbleStyle(), + hasHeaderText = content.header?.text?.isNotEmpty ?? false, + hasImageLink = content.header?.image?.link?.isNotEmpty ?? false, + hasVideoLink = content.header?.video?.link?.isNotEmpty ?? false, + hasDocumentLink = content.header?.document?.link?.isNotEmpty ?? false, + hasButtons = content.action?.buttons?.isNotEmpty ?? false { + isDefaultBubbleColors = this.style.isDefaultBubbleBackground(align); + isLightBubbleBackground = this.style.isLightBubbleBackground(align); + } + + List get _headerBorderRadius => [ + ...(borderRadius.contains(DSBorderRadius.all) + ? [ + DSBorderRadius.topLeft, + DSBorderRadius.topRight, + ] + : borderRadius), + align == DSAlign.left + ? DSBorderRadius.bottomRight + : DSBorderRadius.bottomLeft, + ]; + + List get _buttonsBorderRadius => [ + ...(borderRadius.contains(DSBorderRadius.all) + ? [ + DSBorderRadius.bottomLeft, + DSBorderRadius.bottomRight, + ] + : borderRadius), + align == DSAlign.left + ? DSBorderRadius.topRight + : DSBorderRadius.topLeft, + ]; + + @override + Widget build(BuildContext context) => Column( + children: [ + _buildHeaderBubble(), + const SizedBox( + height: 3.0, + ), + _buildButtonsBubble(), + ], + ); + + Widget _buildHeaderBubble() => switch (content.header?.type) { + DSInteractiveMessageHeaderType.text => _buildText(), + DSInteractiveMessageHeaderType.image => _buildImage(), + DSInteractiveMessageHeaderType.video => _buildVideo(), + DSInteractiveMessageHeaderType.document => _buildDocument(), + _ => _buildUnsupportedContent(), + }; + + Widget _buildText() => hasHeaderText + ? DSTextMessageBubble( + text: content.header!.text!, + align: align, + borderRadius: _headerBorderRadius, + style: style, + ) + : _buildUnsupportedContent(); + + Widget _buildImage() => hasImageLink + ? DSImageMessageBubble( + url: content.header!.image!.link!, + appBarText: (align == DSAlign.left + ? avatarConfig.receivedName + : avatarConfig.sentName) ?? + '', + text: content.header?.text, + align: align, + borderRadius: _headerBorderRadius, + style: style, + ) + : _buildUnsupportedContent(); + + Widget _buildVideo() => hasVideoLink + ? DSVideoMessageBubble( + url: content.header!.video!.link!, + appBarText: (align == DSAlign.left + ? avatarConfig.receivedName + : avatarConfig.sentName) ?? + '', + mediaSize: 0, + text: content.header?.text, + align: align, + borderRadius: _headerBorderRadius, + style: style, + ) + : _buildUnsupportedContent(); + + Widget _buildDocument() => hasDocumentLink + ? DSFileMessageBubble( + url: content.header!.document!.link!, + filename: + content.header!.document!.filename ?? DSUtils.generateUniqueID(), + size: 0, + style: style, + align: align, + borderRadius: _headerBorderRadius, + ) + : _buildUnsupportedContent(); + + Widget _buildUnsupportedContent() => DSUnsupportedContentMessageBubble( + align: align, + borderRadius: _headerBorderRadius, + style: style, + ); + + Widget _buildButtonsBubble() => DSMessageBubble( + align: align, + borderRadius: _buttonsBorderRadius, + style: style, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: _buildButtons(), + ), + ); + + List _buildButtons() { + final widgets = []; + + if (hasButtons) { + var count = 1; + + for (final button in content.action!.buttons!) { + final hasTitle = button.title?.isNotEmpty ?? false; + + if (hasTitle) { + widgets.add( + DSMenuItem( + text: button.title!, + align: align, + style: style, + showBorder: count != content.action!.buttons!.length, + ), + ); + } + + ++count; + } + } + + return widgets; + } +} diff --git a/lib/src/widgets/chat/ds_interactive_list_message_bubble.widget.dart b/lib/src/widgets/chat/ds_interactive_list_message_bubble.widget.dart new file mode 100644 index 00000000..92831a7f --- /dev/null +++ b/lib/src/widgets/chat/ds_interactive_list_message_bubble.widget.dart @@ -0,0 +1,239 @@ +import 'package:flutter/material.dart'; + +import '../../enums/ds_align.enum.dart'; +import '../../enums/ds_border_radius.enum.dart'; +import '../../models/ds_message_bubble_style.model.dart'; +import '../../models/interactive_message/ds_interactive_message.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 '../buttons/ds_menu_item.widget.dart'; +import '../texts/ds_body_text.widget.dart'; +import '../texts/ds_caption_text.widget.dart'; +import '../utils/ds_divider.widget.dart'; +import 'ds_message_bubble.widget.dart'; + +class DSInteractiveListMessageBubble extends StatelessWidget { + final DSInteractiveMessage content; + final DSAlign align; + final List borderRadius; + final DSMessageBubbleStyle style; + + late final bool isDefaultBubbleColors; + late final bool isLightBubbleBackground; + + final bool hasBodyText; + final bool hasFooterText; + final bool hasButtonText; + final bool hasSections; + + DSInteractiveListMessageBubble({ + super.key, + required this.content, + required this.align, + this.borderRadius = const [DSBorderRadius.all], + DSMessageBubbleStyle? style, + }) : style = style ?? DSMessageBubbleStyle(), + hasBodyText = content.body?.text?.isNotEmpty ?? false, + hasFooterText = content.footer?.text?.isNotEmpty ?? false, + hasButtonText = content.action?.button?.isNotEmpty ?? false, + hasSections = content.action?.sections?.isNotEmpty ?? false { + isDefaultBubbleColors = this.style.isDefaultBubbleBackground(align); + isLightBubbleBackground = this.style.isLightBubbleBackground(align); + } + + List get _headerBorderRadius => [ + ...(borderRadius.contains(DSBorderRadius.all) + ? [ + DSBorderRadius.topLeft, + DSBorderRadius.topRight, + ] + : borderRadius), + align == DSAlign.left + ? DSBorderRadius.bottomRight + : DSBorderRadius.bottomLeft, + ]; + + List get _listBorderRadius => [ + ...(borderRadius.contains(DSBorderRadius.all) + ? [ + DSBorderRadius.bottomLeft, + DSBorderRadius.bottomRight, + ] + : borderRadius), + align == DSAlign.left + ? DSBorderRadius.topRight + : DSBorderRadius.topLeft, + ]; + + @override + Widget build(BuildContext context) => Column( + children: [ + _buildHeaderBubble(), + const SizedBox( + height: 3.0, + ), + _buildListBubble(), + ], + ); + + Widget _buildHeaderBubble() => DSMessageBubble( + align: align, + borderRadius: _headerBorderRadius, + style: style, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ..._buildHeaderText(), + _buildHeaderButton(), + ], + ), + ); + + Widget _buildListBubble() => DSMessageBubble( + align: align, + borderRadius: _listBorderRadius, + style: style, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: _buildList(), + ), + ); + + List _buildHeaderText() { + const bottomPadding = 8.0; + final widgets = []; + + if (hasBodyText) { + widgets.add( + Padding( + padding: const EdgeInsets.only( + bottom: bottomPadding, + ), + child: DSBodyText(content.body!.text, + overflow: TextOverflow.visible, + color: isLightBubbleBackground + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow), + ), + ); + } + + if (hasFooterText) { + widgets.add( + Padding( + padding: const EdgeInsets.only( + bottom: bottomPadding, + ), + child: DSCaptionText( + content.footer!.text, + fontStyle: FontStyle.italic, + overflow: TextOverflow.visible, + color: isLightBubbleBackground + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow, + ), + ), + ); + } + + if (widgets.isNotEmpty) { + widgets.add( + Padding( + padding: const EdgeInsets.only( + bottom: bottomPadding, + ), + child: DSDivider( + color: isLightBubbleBackground + ? isDefaultBubbleColors + ? DSColors.neutralMediumWave + : DSColors.neutralDarkCity + : isDefaultBubbleColors + ? DSColors.neutralDarkRooftop + : DSColors.neutralLightSnow, + ), + ), + ); + } + + return widgets; + } + + Widget _buildHeaderButton() => Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.only( + right: hasButtonText ? 4.0 : 0.0, + ), + child: Icon( + DSIcons.list_outline, + size: 20.0, + color: isLightBubbleBackground + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow, + ), + ), + if (hasButtonText) + DSCaptionText( + content.action!.button, + fontWeight: DSFontWeights.bold, + overflow: TextOverflow.visible, + color: isLightBubbleBackground + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow, + ), + ], + ); + + List _buildList() { + final widgets = []; + + if (hasSections) { + for (final section in content.action!.sections!) { + final hasRows = section.rows?.isNotEmpty ?? false; + final hasSectionTitle = section.title?.isNotEmpty ?? false; + + if (hasSectionTitle) { + widgets.add( + Padding( + padding: EdgeInsets.only( + bottom: hasRows ? 8.0 : 0.0, + ), + child: DSBodyText( + section.title!, + overflow: TextOverflow.visible, + color: isLightBubbleBackground + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow, + ), + ), + ); + } + + if (hasRows) { + var count = 1; + + for (final row in section.rows!) { + final hasRowTitle = row.title?.isNotEmpty ?? false; + + if (hasRowTitle) { + widgets.add( + DSMenuItem( + text: row.title!, + align: align, + style: style, + showBorder: count != section.rows!.length, + ), + ); + } + + ++count; + } + } + } + } + + return widgets; + } +} diff --git a/lib/src/widgets/chat/ds_quick_reply.widget.dart b/lib/src/widgets/chat/ds_quick_reply.widget.dart index 72ffc114..72318cd1 100644 --- a/lib/src/widgets/chat/ds_quick_reply.widget.dart +++ b/lib/src/widgets/chat/ds_quick_reply.widget.dart @@ -38,9 +38,8 @@ class DSQuickReply extends StatelessWidget { borderRadius = []; - List options = content['options'] - .map((doc) => DSSelectOptionModel.fromJson(doc)) - .toList(); + List options = + content['options'].map((doc) => DSSelectOption.fromJson(doc)).toList(); for (var option in options) { children.add( diff --git a/lib/src/widgets/chat/ds_select_menu.widget.dart b/lib/src/widgets/chat/ds_select_menu.widget.dart index 1e6ccc19..70889ccc 100644 --- a/lib/src/widgets/chat/ds_select_menu.widget.dart +++ b/lib/src/widgets/chat/ds_select_menu.widget.dart @@ -13,13 +13,12 @@ class DSSelectMenu extends StatelessWidget { final DSMessageBubbleStyle style; DSSelectMenu({ - Key? key, + super.key, required this.align, required this.content, this.onSelected, DSMessageBubbleStyle? style, - }) : style = style ?? DSMessageBubbleStyle(), - super(key: key); + }) : style = style ?? DSMessageBubbleStyle(); @override Widget build(BuildContext context) { @@ -36,9 +35,8 @@ class DSSelectMenu extends StatelessWidget { int count = 0; - List options = content['options'] - .map((doc) => DSSelectOptionModel.fromJson(doc)) - .toList(); + List options = + content['options'].map((doc) => DSSelectOption.fromJson(doc)).toList(); for (final option in options) { count++; diff --git a/lib/src/widgets/utils/ds_card.widget.dart b/lib/src/widgets/utils/ds_card.widget.dart index 1159404b..394672c7 100644 --- a/lib/src/widgets/utils/ds_card.widget.dart +++ b/lib/src/widgets/utils/ds_card.widget.dart @@ -11,7 +11,7 @@ import '../../models/ds_message_bubble_style.model.dart'; import '../../services/ds_file.service.dart'; import '../../utils/ds_message_content_type.util.dart'; import '../chat/audio/ds_audio_message_bubble.widget.dart'; -import '../chat/ds_application_json_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_file_message_bubble.widget.dart'; @@ -149,6 +149,7 @@ class DSCard extends StatelessWidget { style: style, content: content, status: status, + avatarConfig: avatarConfig, ); default: diff --git a/lib/src/widgets/utils/ds_group_card.widget.dart b/lib/src/widgets/utils/ds_group_card.widget.dart index 5224557c..25946c0f 100644 --- a/lib/src/widgets/utils/ds_group_card.widget.dart +++ b/lib/src/widgets/utils/ds_group_card.widget.dart @@ -22,7 +22,7 @@ import 'ds_user_avatar.widget.dart'; // Default compare message function // ignore: prefer_function_declarations_over_variables final _defaultCompareMessageFuntion = - (DSMessageItemModel firstMsg, DSMessageItemModel secondMsg) { + (DSMessageItem firstMsg, DSMessageItem secondMsg) { bool shouldGroupSelect = true; if (firstMsg.type == DSMessageContentType.select || @@ -62,14 +62,14 @@ class DSGroupCard extends StatefulWidget { this.onInfinitScroll, this.shrinkWrap = false, DSMessageBubbleStyle? style, - bool Function(DSMessageItemModel, DSMessageItemModel)? compareMessages, + bool Function(DSMessageItem, DSMessageItem)? compareMessages, ScrollController? scrollController, }) : compareMessages = compareMessages ?? _defaultCompareMessageFuntion, style = style ?? DSMessageBubbleStyle(), scrollController = scrollController ?? ScrollController(); - final List documents; - final bool Function(DSMessageItemModel, DSMessageItemModel) compareMessages; + final List documents; + final bool Function(DSMessageItem, DSMessageItem) compareMessages; final bool isComposing; final bool sortMessages; final void Function(String, Map)? onSelected; @@ -190,9 +190,9 @@ class _DSGroupCardState extends State { }; for (int i = 1; i < widget.documents.length; i++) { - DSMessageItemModel message = widget.documents[i]; + DSMessageItem message = widget.documents[i]; - List groupMsgs = group['msgs']; + List groupMsgs = group['msgs']; if (widget.compareMessages(message, groupMsgs.last)) { group['msgs'].add(message); @@ -239,10 +239,10 @@ class _DSGroupCardState extends State { int msgCount = 1; final sentMessage = group['align'] == DSAlign.right; - DSMessageItemModel? lastMessageQuickReply; + DSMessageItem? lastMessageQuickReply; group['msgs'].forEach( - (DSMessageItemModel message) { + (DSMessageItem message) { final rows = []; final int length = group['msgs'].length; List borderRadius = diff --git a/pubspec.yaml b/pubspec.yaml index 718fc34f..1cd2a63d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: blip_ds description: Blip Design System for Flutter. -version: 0.0.87 +version: 0.0.88 homepage: https://github.com/takenet/blip-ds-flutter#readme repository: https://github.com/takenet/blip-ds-flutter diff --git a/sample/android/build.gradle b/sample/android/build.gradle index 59437ce1..a81ceb71 100644 --- a/sample/android/build.gradle +++ b/sample/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.6.10' + ext.kotlin_version = '1.9.20' repositories { google() mavenCentral() diff --git a/sample/lib/controllers/sample_group_card.controller.dart b/sample/lib/controllers/sample_group_card.controller.dart index af45068e..57514571 100644 --- a/sample/lib/controllers/sample_group_card.controller.dart +++ b/sample/lib/controllers/sample_group_card.controller.dart @@ -5,14 +5,14 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; class SampleGroupCardController { - Future> getMessages() async { + Future> getMessages() async { String data = await DefaultAssetBundle.of(Get.context!) .loadString("assets/messages.json"); final jsonResult = jsonDecode(data); final messages = (jsonResult as List) .map( - (doc) => DSMessageItemModel.fromJson( + (doc) => DSMessageItem.fromJson( { "id": doc["id"], "date": doc["date"], diff --git a/sample/lib/widgets/showcase/sample_group_card.showcase.dart b/sample/lib/widgets/showcase/sample_group_card.showcase.dart index 17cf24fb..46055753 100644 --- a/sample/lib/widgets/showcase/sample_group_card.showcase.dart +++ b/sample/lib/widgets/showcase/sample_group_card.showcase.dart @@ -26,7 +26,7 @@ class SampleGroupCardShowcase extends StatelessWidget { debugPrint('Infos de callback: $text / $payload'); }, isComposing: false, - documents: snapshot.data as List, + documents: snapshot.data as List, style: DSMessageBubbleStyle( sentBackgroundColor: DSColors.neutralLightSnow, receivedBackgroundColor: const Color(0xff02afff), diff --git a/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart b/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart index 4e226076..c19006f9 100644 --- a/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart +++ b/sample/lib/widgets/showcase/sample_message_bubble.showcase.dart @@ -53,6 +53,100 @@ class SampleMessageBubbleShowcase extends StatelessWidget { return Obx( () => Column( children: [ + DSApplicationJsonMessageBubble( + align: DSAlign.left, + borderRadius: const [DSBorderRadius.all], + content: const { + "recipient_type": "individual", + "type": "interactive", + "interactive": { + "type": "button", + "header": { + "type": "video", + "text": "video blip", + "video": { + "link": + "http://techslides.com/demos/sample-videos/small.mp4" + } + }, + "body": {"text": "Button Body Message"}, + "action": { + "buttons": [ + { + "type": "reply", + "reply": {"id": "unique-postback-id", "title": "First"} + }, + { + "type": "reply", + "reply": {"id": "unique-id", "title": "Second"} + } + ] + } + } + }, + ), + DSApplicationJsonMessageBubble( + align: DSAlign.left, + borderRadius: const [DSBorderRadius.all], + content: const { + "recipient_type": "individual", + "type": "interactive", + "interactive": { + "type": "list", + "body": { + "text": + "Tenho mais algumas perguntas, mas prometo que vamos ser agéis. Gostaríamos de saber: Em qual segmento sua empresa atua? Essa informação nos ajudará a direcioná-lo para o atendimento ideal." + }, + "action": { + "button": "Selecione uma opção", + "sections": [ + { + "rows": [ + {"id": "1", "title": "Esq. de Alumínio"}, + {"id": "2", "title": "Vidraceiro"}, + {"id": "3", "title": "Distribuidor"}, + {"id": "4", "title": "Sistemista"}, + {"id": "5", "title": "Soluções"}, + {"id": "6", "title": "Outros"} + ] + } + ] + }, + "footer": { + "text": "Clique no botão abaixo para selecionar uma opção" + } + } + }, + ), + DSApplicationJsonMessageBubble( + align: DSAlign.right, + borderRadius: const [DSBorderRadius.all], + content: const { + "recipient_type": "individual", + "type": "interactive", + "interactive": { + "type": "list", + "body": {"text": "Selecione qual é o seu interesse:"}, + "action": { + "button": "Selecione uma opção", + "sections": [ + { + "title": "Título da Seção", + "rows": [ + {"id": "1", "title": "Casas de Festas"}, + {"id": "2", "title": "021 Formatura"}, + {"id": "3", "title": "Bravo"}, + {"id": "4", "title": "Menu anterior"} + ] + } + ] + }, + "footer": { + "text": "Clique no botão abaixo para selecionar uma opção" + } + } + }, + ), DSTextMessageBubble( text: _longText, align: DSAlign.left, diff --git a/sample/macos/Flutter/GeneratedPluginRegistrant.swift b/sample/macos/Flutter/GeneratedPluginRegistrant.swift index 3744928a..82711f78 100644 --- a/sample/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/sample/macos/Flutter/GeneratedPluginRegistrant.swift @@ -8,19 +8,23 @@ import Foundation import audio_session import ffmpeg_kit_flutter_full_gpl import just_audio +import package_info_plus import path_provider_foundation import sqflite import url_launcher_macos import video_compress -import wakelock_macos +import video_player_avfoundation +import wakelock_plus func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) FFmpegKitFlutterPlugin.register(with: registry.registrar(forPlugin: "FFmpegKitFlutterPlugin")) JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin")) + FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) VideoCompressPlugin.register(with: registry.registrar(forPlugin: "VideoCompressPlugin")) - WakelockMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockMacosPlugin")) + FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin")) + WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) } diff --git a/sample/pubspec.lock b/sample/pubspec.lock index 6bc70e19..dcf683a4 100644 --- a/sample/pubspec.lock +++ b/sample/pubspec.lock @@ -21,17 +21,17 @@ packages: dependency: transitive description: name: audio_session - sha256: "8a2bc5e30520e18f3fb0e366793d78057fb64cd5287862c76af0c8771f2a52ad" + sha256: "6fdf255ed3af86535c96452c33ecff1245990bb25a605bfb1958661ccc3d467f" url: "https://pub.dev" source: hosted - version: "0.1.16" + version: "0.1.18" blip_ds: dependency: "direct main" description: path: ".." relative: true source: path - version: "0.0.86" + version: "0.0.88" boolean_selector: dependency: transitive description: @@ -44,26 +44,26 @@ packages: dependency: transitive description: name: cached_network_image - sha256: fd3d0dc1d451f9a252b32d95d3f0c3c487bc41a75eba2e6097cb0b9c71491b15 + sha256: f98972704692ba679db144261172a8e20feb145636c617af0eb4022132a6797f url: "https://pub.dev" source: hosted - version: "3.2.3" + version: "3.3.0" cached_network_image_platform_interface: dependency: transitive description: name: cached_network_image_platform_interface - sha256: bb2b8403b4ccdc60ef5f25c70dead1f3d32d24b9d6117cfc087f496b178594a7 + sha256: "56aa42a7a01e3c9db8456d9f3f999931f1e05535b5a424271e9a38cabf066613" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "3.0.0" cached_network_image_web: dependency: transitive description: name: cached_network_image_web - sha256: b8eb814ebfcb4dea049680f8c1ffb2df399e4d03bf7a352c775e26fa06e02fa0 + sha256: "759b9a9f8f6ccbb66c185df805fac107f05730b1dab9c64626d1008cca532257" url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.1.0" characters: dependency: transitive description: @@ -84,10 +84,10 @@ packages: dependency: transitive description: name: chewie - sha256: e9da4898ee4859825404f507969f57113c04ca0060e152b95c9afd73934126ad + sha256: ccfce3350ae9fd419cd336cdf3380f77a08e45171e1e3cb3d499d204de5e7ea8 url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.7.1" clock: dependency: transitive description: @@ -116,18 +116,26 @@ packages: dependency: transitive description: name: csslib - sha256: b36c7f7e24c0bdf1bf9a3da461c837d1de64b9f8beb190c9011d8c72a3dfd745 + sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" url: "https://pub.dev" source: hosted - version: "0.17.2" + version: "1.0.0" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be + sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d + url: "https://pub.dev" + source: hosted + version: "1.0.6" + dbus: + dependency: transitive + description: + name: dbus + sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "0.7.10" debounce_throttle: dependency: transitive description: @@ -140,18 +148,18 @@ packages: dependency: transitive description: name: dio - sha256: a9d76e72985d7087eb7c5e7903224ae52b337131518d127c554b9405936752b8 + sha256: "417e2a6f9d83ab396ec38ff4ea5da6c254da71e4db765ad737a42af6930140b7" url: "https://pub.dev" source: hosted - version: "5.2.1+1" + version: "5.3.3" dotted_border: dependency: transitive description: name: dotted_border - sha256: "07a5c5e8d4e6e992279e190e0352be8faa5b8f96d81c77a78b2d42f060279840" + sha256: "108837e11848ca776c53b30bc870086f84b62ed6e01c503ed976e8f8c7df9c04" url: "https://pub.dev" source: hosted - version: "2.0.0+3" + version: "2.1.0" fake_async: dependency: transitive description: @@ -164,10 +172,10 @@ packages: dependency: transitive description: name: ffi - sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 + sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" ffmpeg_kit_flutter_full_gpl: dependency: transitive description: @@ -188,10 +196,10 @@ packages: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.0" file_sizes: dependency: transitive description: @@ -205,30 +213,22 @@ packages: description: flutter source: sdk version: "0.0.0" - flutter_blurhash: - dependency: transitive - description: - name: flutter_blurhash - sha256: "05001537bd3fac7644fa6558b09ec8c0a3f2eba78c0765f88912882b1331a5c6" - url: "https://pub.dev" - source: hosted - version: "0.7.0" flutter_cache_manager: dependency: transitive description: name: flutter_cache_manager - sha256: "32cd900555219333326a2d0653aaaf8671264c29befa65bbd9856d204a4c9fb3" + sha256: "8207f27539deb83732fdda03e259349046a39a4c767269285f449ade355d54ba" url: "https://pub.dev" source: hosted - version: "3.3.0" + version: "3.3.1" flutter_lints: dependency: "direct dev" description: name: flutter_lints - sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c + sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.3" flutter_lorem: dependency: "direct main" description: @@ -241,18 +241,18 @@ packages: dependency: transitive description: name: flutter_spinkit - sha256: "77a2117c0517ff909221f3160b8eb20052ab5216107581168af574ac1f05dff8" + sha256: b39c753e909d4796906c5696a14daf33639a76e017136c8d82bf3e620ce5bb8e url: "https://pub.dev" source: hosted - version: "5.1.0" + version: "5.2.0" flutter_svg: dependency: transitive description: name: flutter_svg - sha256: "8c5d68a82add3ca76d792f058b186a0599414f279f00ece4830b9b231b570338" + sha256: d39e7f95621fc84376bc0f7d504f05c3a41488c562f4a8ad410569127507402c url: "https://pub.dev" source: hosted - version: "2.0.7" + version: "2.0.9" flutter_test: dependency: "direct dev" description: flutter @@ -267,26 +267,26 @@ packages: dependency: "direct main" description: name: get - sha256: "2ba20a47c8f1f233bed775ba2dd0d3ac97b4cf32fc17731b3dfc672b06b0e92a" + sha256: e4e7335ede17452b391ed3b2ede016545706c01a02292a6c97619705e7d2a85e url: "https://pub.dev" source: hosted - version: "4.6.5" + version: "4.6.6" html: dependency: transitive description: name: html - sha256: d9793e10dbe0e6c364f4c59bf3e01fb33a9b2a674bc7a1081693dba0614b6269 + sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" url: "https://pub.dev" source: hosted - version: "0.15.1" + version: "0.15.4" http: dependency: transitive description: name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" url: "https://pub.dev" source: hosted - version: "0.13.5" + version: "0.13.6" http_parser: dependency: transitive description: @@ -307,26 +307,26 @@ packages: dependency: transitive description: name: just_audio - sha256: "5ed0cd723e17dfd8cd4b0253726221e67f6546841ea4553635cf895061fc335b" + sha256: b607cd1a43bac03d85c3aaee00448ff4a589ef2a77104e3d409889ff079bf823 url: "https://pub.dev" source: hosted - version: "0.9.35" + version: "0.9.36" just_audio_platform_interface: dependency: transitive description: name: just_audio_platform_interface - sha256: d8409da198bbc59426cd45d4c92fca522a2ec269b576ce29459d6d6fcaeb44df + sha256: c3dee0014248c97c91fe6299edb73dc4d6c6930a2f4f713579cd692d9e47f4a1 url: "https://pub.dev" source: hosted - version: "4.2.1" + version: "4.2.2" just_audio_web: dependency: transitive description: name: just_audio_web - sha256: ff62f733f437b25a0ff590f0e295fa5441dcb465f1edbdb33b3dea264705bc13 + sha256: "134356b0fe3d898293102b33b5fd618831ffdc72bb7a1b726140abdf22772b70" url: "https://pub.dev" source: hosted - version: "0.4.8" + version: "0.4.9" linkify: dependency: transitive description: @@ -339,10 +339,10 @@ packages: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.1" map_launcher: dependency: transitive description: @@ -355,10 +355,10 @@ packages: dependency: transitive description: name: mask_text_input_formatter - sha256: "19bb7809c3c2559277e95521b3ee421e1409eb2cc85efd2feb191696c92490f4" + sha256: fc7a1d59262bbaa97b1e1bf009c2c045163e70f229f6c146bfb17a84cfd8635d url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.6.0" matcher: dependency: transitive description: @@ -411,18 +411,34 @@ packages: dependency: transitive description: name: octo_image - sha256: "107f3ed1330006a3bea63615e81cf637433f5135a52466c7caa0e7152bca9143" + sha256: "45b40f99622f11901238e18d48f5f12ea36426d8eced9f4cbf58479c7aa2430d" url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "2.0.0" open_filex: dependency: transitive description: name: open_filex - sha256: "854aefd72dfd74219dc8c8d1767c34ec1eae64b8399a5be317bddb1ec2108915" + sha256: a6c95237767c5647e68b71a476602fcf4f1bfc530c126265e53addae22ef5fc2 + url: "https://pub.dev" + source: hosted + version: "4.3.4" + package_info_plus: + dependency: transitive + description: + name: package_info_plus + sha256: "7e76fad405b3e4016cd39d08f455a4eb5199723cf594cd1b8916d47140d93017" + url: "https://pub.dev" + source: hosted + version: "4.2.0" + package_info_plus_platform_interface: + dependency: transitive + description: + name: package_info_plus_platform_interface + sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6" url: "https://pub.dev" source: hosted - version: "4.3.2" + version: "2.0.1" path: dependency: transitive description: @@ -459,10 +475,10 @@ packages: dependency: transitive description: name: path_provider_android - sha256: "6b8b19bd80da4f11ce91b2d1fb931f3006911477cec227cce23d3253d80df3f1" + sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72 url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.2.1" path_provider_foundation: dependency: transitive description: @@ -495,14 +511,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.1" - pedantic: - dependency: transitive - description: - name: pedantic - sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602" - url: "https://pub.dev" - source: hosted - version: "1.11.1" petitparser: dependency: transitive description: @@ -523,42 +531,34 @@ packages: dependency: transitive description: name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.3" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc" + sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.7" pointer_interceptor: dependency: transitive description: name: pointer_interceptor - sha256: fee6ba42b910637465bc0d367ba27066c6eccfbc3bc0ceb14831915acc600db0 - url: "https://pub.dev" - source: hosted - version: "0.9.3+3" - process: - dependency: transitive - description: - name: process - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + sha256: adf7a637f97c077041d36801b43be08559fd4322d2127b3f20bb7be1b9eebc22 url: "https://pub.dev" source: hosted - version: "4.2.4" + version: "0.9.3+7" provider: dependency: transitive description: name: provider - sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f + sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096" url: "https://pub.dev" source: hosted - version: "6.0.5" + version: "6.1.1" rxdart: dependency: transitive description: @@ -604,22 +604,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.10.0" + sprintf: + dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.dev" + source: hosted + version: "7.0.0" sqflite: dependency: transitive description: name: sqflite - sha256: "78324387dc81df14f78df06019175a86a2ee0437624166c382e145d0a7fd9a4f" + sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a" url: "https://pub.dev" source: hosted - version: "2.2.4+1" + version: "2.3.0" sqflite_common: dependency: transitive description: name: sqflite_common - sha256: bfd6973aaeeb93475bc0d875ac9aefddf7965ef22ce09790eb963992ffc5183f + sha256: bb4738f15b23352822f4c42a531677e5c6f522e079461fd240ead29d8d8a54a6 url: "https://pub.dev" source: hosted - version: "2.4.2+2" + version: "2.5.0+2" stack_trace: dependency: transitive description: @@ -664,10 +672,10 @@ packages: dependency: transitive description: name: synchronized - sha256: "33b31b6beb98100bf9add464a36a8dd03eb10c7a8cf15aeec535e9b054aaf04b" + sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.1.0" term_glyph: dependency: transitive description: @@ -688,122 +696,122 @@ packages: dependency: transitive description: name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" universal_html: dependency: transitive description: name: universal_html - sha256: "5ff50b7c14d201421cf5230ec389a0591c4deb5c817c9d7ccca3b26fe5f31e34" + sha256: "56536254004e24d9d8cfdb7dbbf09b74cf8df96729f38a2f5c238163e3d58971" url: "https://pub.dev" source: hosted - version: "2.0.8" + version: "2.2.4" universal_io: dependency: transitive description: name: universal_io - sha256: "79f78ddad839ee3aae3ec7c01eb4575faf0d5c860f8e5223bc9f9c17f7f03cef" + sha256: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad" url: "https://pub.dev" source: hosted - version: "2.0.4" + version: "2.2.2" url_launcher: dependency: transitive description: name: url_launcher - sha256: "698fa0b4392effdc73e9e184403b627362eb5fbf904483ac9defbb1c2191d809" + sha256: b1c9e98774adf8820c96fbc7ae3601231d324a7d5ebd8babe27b6dfac91357ba url: "https://pub.dev" source: hosted - version: "6.1.8" + version: "6.2.1" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "3e2f6dfd2c7d9cd123296cab8ef66cfc2c1a13f5845f42c7a0f365690a8a7dd1" + sha256: "31222ffb0063171b526d3e569079cf1f8b294075ba323443fdc690842bfd4def" url: "https://pub.dev" source: hosted - version: "6.0.23" + version: "6.2.0" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: bb328b24d3bccc20bdf1024a0990ac4f869d57663660de9c936fb8c043edefe3 + sha256: bba3373219b7abb6b5e0d071b0fe66dfbe005d07517a68e38d4fc3638f35c6d3 url: "https://pub.dev" source: hosted - version: "6.0.18" + version: "6.2.1" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: "318c42cba924e18180c029be69caf0a1a710191b9ec49bb42b5998fdcccee3cc" + sha256: "9f2d390e096fdbe1e6e6256f97851e51afc2d9c423d3432f1d6a02a8a9a8b9fd" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.1.0" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - sha256: "41988b55570df53b3dd2a7fc90c76756a963de6a8c5f8e113330cb35992e2094" + sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234 url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.1.0" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface - sha256: "4eae912628763eb48fc214522e58e942fd16ce195407dbf45638239523c759a6" + sha256: "980e8d9af422f477be6948bdfb68df8433be71f5743a188968b0c1b887807e50" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.2.0" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: "44d79408ce9f07052095ef1f9a693c258d6373dc3944249374e30eff7219ccb0" + sha256: "7fd2f55fe86cea2897b963e864dc01a7eb0719ecc65fcef4c1cc3d686d718bb2" url: "https://pub.dev" source: hosted - version: "2.0.14" + version: "2.2.0" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: b6217370f8eb1fd85c8890c539f5a639a01ab209a36db82c921ebeacefc7a615 + sha256: "7754a1ad30ee896b265f8d14078b0513a4dba28d358eabb9d5f339886f4a1adc" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.1.0" uuid: dependency: transitive description: name: uuid - sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" + sha256: df5a4d8f22ee4ccd77f8839ac7cb274ebc11ef9adcce8b92be14b797fe889921 url: "https://pub.dev" source: hosted - version: "3.0.7" + version: "4.2.1" vector_graphics: dependency: transitive description: name: vector_graphics - sha256: "670f6e07aca990b4a2bcdc08a784193c4ccdd1932620244c3a86bb72a0eac67f" + sha256: "0f0c746dd2d6254a0057218ff980fc7f5670fd0fcf5e4db38a490d31eed4ad43" url: "https://pub.dev" source: hosted - version: "1.1.7" + version: "1.1.9+1" vector_graphics_codec: dependency: transitive description: name: vector_graphics_codec - sha256: "7451721781d967db9933b63f5733b1c4533022c0ba373a01bdd79d1a5457f69f" + sha256: "0edf6d630d1bfd5589114138ed8fada3234deacc37966bec033d3047c29248b7" url: "https://pub.dev" source: hosted - version: "1.1.7" + version: "1.1.9+1" vector_graphics_compiler: dependency: transitive description: name: vector_graphics_compiler - sha256: "80a13c613c8bde758b1464a1755a7b3a8f2b6cec61fbf0f5a53c94c30f03ba2e" + sha256: d24333727332d9bd20990f1483af4e09abdb9b1fc7c3db940b56ab5c42790c26 url: "https://pub.dev" source: hosted - version: "1.1.7" + version: "1.1.9+1" vector_math: dependency: transitive description: @@ -824,82 +832,58 @@ packages: dependency: transitive description: name: video_player - sha256: "3fd106c74da32f336dc7feb65021da9b0207cb3124392935f1552834f7cce822" + sha256: e16f0a83601a78d165dabc17e4dac50997604eb9e4cc76e10fa219046b70cef3 url: "https://pub.dev" source: hosted - version: "2.7.0" + version: "2.8.1" video_player_android: dependency: transitive description: name: video_player_android - sha256: "984388511230bac63feb53b2911a70e829fe0976b6b2213f5c579c4e0a882db3" + sha256: "3fe89ab07fdbce786e7eb25b58532d6eaf189ceddc091cb66cba712f8d9e8e55" url: "https://pub.dev" source: hosted - version: "2.3.10" + version: "2.4.10" video_player_avfoundation: dependency: transitive description: name: video_player_avfoundation - sha256: d9f7a46d6a77680adb03ec05a381025d6e890ebe636637c6c3014cc3926b97e9 + sha256: bc923884640d6dc403050586eb40713cdb8d1d84e6886d8aca50ab04c59124c2 url: "https://pub.dev" source: hosted - version: "2.3.8" + version: "2.5.2" video_player_platform_interface: dependency: transitive description: name: video_player_platform_interface - sha256: a8c4dcae2a7a6e7cc1d7f9808294d968eca1993af34a98e95b9bdfa959bec684 + sha256: be72301bf2c0150ab35a8c34d66e5a99de525f6de1e8d27c0672b836fe48f73a url: "https://pub.dev" source: hosted - version: "6.1.0" + version: "6.2.1" video_player_web: dependency: transitive description: name: video_player_web - sha256: b649b07b8f8f553bee4a97a0a53d0fe78a70b115eafaf0105b612b32b05ddb99 - url: "https://pub.dev" - source: hosted - version: "2.0.13" - wakelock: - dependency: transitive - description: - name: wakelock - sha256: "769ecf42eb2d07128407b50cb93d7c10bd2ee48f0276ef0119db1d25cc2f87db" - url: "https://pub.dev" - source: hosted - version: "0.6.2" - wakelock_macos: - dependency: transitive - description: - name: wakelock_macos - sha256: "047c6be2f88cb6b76d02553bca5a3a3b95323b15d30867eca53a19a0a319d4cd" + sha256: ab7a462b07d9ca80bed579e30fb3bce372468f1b78642e0911b10600f2c5cb5b url: "https://pub.dev" source: hosted - version: "0.4.0" - wakelock_platform_interface: + version: "2.1.2" + wakelock_plus: dependency: transitive description: - name: wakelock_platform_interface - sha256: "1f4aeb81fb592b863da83d2d0f7b8196067451e4df91046c26b54a403f9de621" + name: wakelock_plus + sha256: f45a6c03aa3f8322e0a9d7f4a0482721c8789cb41d555407367650b8f9c26018 url: "https://pub.dev" source: hosted - version: "0.3.0" - wakelock_web: + version: "1.1.3" + wakelock_plus_platform_interface: dependency: transitive description: - name: wakelock_web - sha256: "1b256b811ee3f0834888efddfe03da8d18d0819317f20f6193e2922b41a501b5" + name: wakelock_plus_platform_interface + sha256: "40fabed5da06caff0796dc638e1f07ee395fb18801fbff3255a2372db2d80385" url: "https://pub.dev" source: hosted - version: "0.4.0" - wakelock_windows: - dependency: transitive - description: - name: wakelock_windows - sha256: "857f77b3fe6ae82dd045455baa626bc4b93cb9bb6c86bf3f27c182167c3a5567" - url: "https://pub.dev" - source: hosted - version: "0.2.1" + version: "1.1.0" web: dependency: transitive description: @@ -912,18 +896,18 @@ packages: dependency: transitive description: name: win32 - sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46 + sha256: "7c99c0e1e2fa190b48d25c81ca5e42036d5cac81430ef249027d97b0935c553f" url: "https://pub.dev" source: hosted - version: "3.1.3" + version: "5.1.0" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86 + sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" url: "https://pub.dev" source: hosted - version: "0.2.0+3" + version: "1.0.3" xml: dependency: transitive description: @@ -933,5 +917,5 @@ packages: source: hosted version: "6.3.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" - flutter: ">=3.7.0" + dart: ">=3.1.0 <4.0.0" + flutter: ">=3.13.0"