From f62ff877874f023fb7f6e86403a86800cb79446f Mon Sep 17 00:00:00 2001 From: Andre Rossi Date: Fri, 27 Oct 2023 13:23:32 -0300 Subject: [PATCH 1/2] feat: added a progressive loading --- analysis_options.yaml | 4 ++ .../ds_image_message_bubble.controller.dart | 10 ++-- .../ds_video_message_bubble.controller.dart | 39 ++++++++------- .../video/ds_video_message_bubble.widget.dart | 47 ++++++++++++------- 4 files changed, 58 insertions(+), 42 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index a5744c1c..e0eb3931 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,4 +1,8 @@ include: package:flutter_lints/flutter.yaml +linter: + rules: + - prefer_relative_imports + # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options diff --git a/lib/src/controllers/chat/ds_image_message_bubble.controller.dart b/lib/src/controllers/chat/ds_image_message_bubble.controller.dart index 38baf0f5..7cef0da9 100644 --- a/lib/src/controllers/chat/ds_image_message_bubble.controller.dart +++ b/lib/src/controllers/chat/ds_image_message_bubble.controller.dart @@ -2,12 +2,13 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'package:blip_ds/src/utils/ds_directory_formatter.util.dart'; import 'package:crypto/crypto.dart'; import 'package:get/get.dart'; +import 'package:path/path.dart' as path_utils; import '../../services/ds_auth.service.dart'; import '../../services/ds_file.service.dart'; +import '../../utils/ds_directory_formatter.util.dart'; class DSImageMessageBubbleController extends GetxController { final maximumProgress = RxInt(0); @@ -49,14 +50,11 @@ class DSImageMessageBubbleController extends GetxController { return; } - final fileName = fullPath.split('/').last; - final path = fullPath.substring(0, fullPath.lastIndexOf('/')); - try { final savedFilePath = await DSFileService.download( url, - fileName, - path: path, + path_utils.basename(fullPath), + path: path_utils.dirname(fullPath), onReceiveProgress: _onReceiveProgress, httpHeaders: shouldAuthenticate ? DSAuthService.httpHeaders : null, ); diff --git a/lib/src/controllers/chat/ds_video_message_bubble.controller.dart b/lib/src/controllers/chat/ds_video_message_bubble.controller.dart index 9a73ee87..a8660f57 100644 --- a/lib/src/controllers/chat/ds_video_message_bubble.controller.dart +++ b/lib/src/controllers/chat/ds_video_message_bubble.controller.dart @@ -3,21 +3,22 @@ import 'dart:io'; import 'package:crypto/crypto.dart'; import 'package:ffmpeg_kit_flutter_full_gpl/ffmpeg_kit.dart'; -import 'package:ffmpeg_kit_flutter_full_gpl/return_code.dart'; import 'package:file_sizes/file_sizes.dart'; import 'package:get/get.dart'; +import 'package:path/path.dart' as path_utils; import '../../models/ds_toast_props.model.dart'; import '../../services/ds_file.service.dart'; import '../../services/ds_toast.service.dart'; import '../../utils/ds_directory_formatter.util.dart'; -import '../../widgets/chat/video/ds_video_error.dialog.dart'; class DSVideoMessageBubbleController { final String url; final int mediaSize; final Map? httpHeaders; final String type; + final maximumProgress = RxInt(0); + final downloadProgress = RxInt(0); DSVideoMessageBubbleController({ required this.url, @@ -90,28 +91,17 @@ class DSVideoMessageBubbleController { if (!await outputFile.exists()) { final inputFilePath = await DSFileService.download( url, - fileName, + path_utils.basename(fullPath), + path: path_utils.dirname(fullPath), + onReceiveProgress: (current, max) { + downloadProgress.value = current; + maximumProgress.value = max; + }, httpHeaders: httpHeaders, ); - final session = await FFmpegKit.execute( - '-hide_banner -y -i "$inputFilePath" "${outputFile.path}"'); - - File(inputFilePath!).delete(); - - final returnCode = await session.getReturnCode(); - - if (!ReturnCode.isSuccess(returnCode)) { - hasError.value = true; - await DSVideoErrorDialog.show( - filename: fileName, - url: url, - httpHeaders: httpHeaders, - ); - } + _generateThumbnail(inputFilePath!); } - - _generateThumbnail(outputFile.path); } catch (_) { hasError.value = true; @@ -136,4 +126,13 @@ class DSVideoMessageBubbleController { thumbnail.value = thumbnailPath; } + + String getDownloadProgress() { + String getSize(int value) => FileSize.getSize( + value, + precision: PrecisionValue.One, + ); + + return '${getSize(downloadProgress.value)} / ${getSize(maximumProgress.value)}'; + } } diff --git a/lib/src/widgets/chat/video/ds_video_message_bubble.widget.dart b/lib/src/widgets/chat/video/ds_video_message_bubble.widget.dart index 33a3916b..0d1e4196 100644 --- a/lib/src/widgets/chat/video/ds_video_message_bubble.widget.dart +++ b/lib/src/widgets/chat/video/ds_video_message_bubble.widget.dart @@ -10,8 +10,8 @@ import '../../../models/ds_message_bubble_style.model.dart'; import '../../../services/ds_auth.service.dart'; import '../../../themes/colors/ds_colors.theme.dart'; import '../../../themes/icons/ds_icons.dart'; -import '../../animations/ds_fading_circle_loading.widget.dart'; import '../../buttons/ds_button.widget.dart'; +import '../../texts/ds_caption_small_text.widget.dart'; import '../ds_message_bubble.widget.dart'; import '../ds_show_more_text.widget.dart'; import 'ds_video_body.widget.dart'; @@ -135,21 +135,8 @@ class _DSVideoMessageBubbleState extends State size: 80.0, color: DSColors.neutralDarkRooftop, ) - : (_controller.isDownloading.value || - _controller.isLoadingThumbnail.value) - ? Center( - child: Container( - height: 50.0, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: foregroundColor, - ), - child: DSFadingCircleLoading( - color: backgroundLoadingColor, - size: 45.0, - ), - ), - ) + : _controller.isDownloading.value + ? _buildDownloadProgress(foregroundColor) : _controller.thumbnail.isEmpty ? Center( child: SizedBox( @@ -204,4 +191,32 @@ class _DSVideoMessageBubbleState extends State ), ); } + + Widget _buildDownloadProgress(final Color foregroundColor) { + final double percent = _controller.maximumProgress.value > 0 + ? _controller.downloadProgress.value / _controller.maximumProgress.value + : 0; + + return AnimatedOpacity( + opacity: _controller.maximumProgress.value > 0 ? 1 : 0, + duration: const Duration(milliseconds: 250), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: CircularProgressIndicator( + color: foregroundColor, + backgroundColor: Colors.grey, + value: percent, + ), + ), + DSCaptionSmallText( + _controller.getDownloadProgress(), + color: foregroundColor, + ) + ], + ), + ); + } } From 79b560cf2d9c15be1b4f8640c55bcecd80364184 Mon Sep 17 00:00:00 2001 From: Andre Rossi Date: Mon, 30 Oct 2023 13:38:33 -0300 Subject: [PATCH 2/2] chore: update new version --- CHANGELOG.md | 4 ++++ pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa37039a..1f1910da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.85 + +- [DSVideoMessageBubble] Added a progressive loading + ## 0.0.84 - [DSImageMessageBubble] Improved the performance of the image bubble diff --git a/pubspec.yaml b/pubspec.yaml index e4986f77..f66c5c4f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: blip_ds description: Blip Design System for Flutter. -version: 0.0.84 +version: 0.0.85 homepage: https://github.com/takenet/blip-ds-flutter#readme repository: https://github.com/takenet/blip-ds-flutter