Skip to content

Commit

Permalink
Merge branch 'develop' into feature/532627-text-reply
Browse files Browse the repository at this point in the history
  • Loading branch information
Andre Rossi committed Nov 28, 2023
2 parents 45e22aa + 7d543e0 commit f7cd019
Show file tree
Hide file tree
Showing 16 changed files with 334 additions and 182 deletions.
1 change: 1 addition & 0 deletions lib/src/controllers/chat/ds_audio_player.controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class DSAudioPlayerController extends GetxController {
final audioSpeed = RxDouble(1.0);
final player = AudioPlayer();
final isInitialized = RxBool(false);
final isLoadingAudio = RxBool(false);

/// Collects the data useful for displaying in a SeekBar widget.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ class DSImageMessageBubbleController extends GetxController {
final maximumProgress = RxInt(0);
final downloadProgress = RxInt(0);
final localPath = RxnString();

final String url;
final String? mediaType;
final bool shouldAuthenticate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class DSVideoMessageBubbleController {
hasError.value = !isSuccess;
}

_generateThumbnail(outputFile.path);
await _generateThumbnail(outputFile.path);
} catch (_) {
hasError.value = true;

Expand Down
11 changes: 11 additions & 0 deletions lib/src/extensions/future.extension.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'package:get/get.dart';

extension FutureExtension on Future {
Future<dynamic> trueWhile<T>(Rx<bool> rxValue) {
rxValue.value = true;

return whenComplete(
() => rxValue.value = false,
);
}
}
7 changes: 6 additions & 1 deletion lib/src/models/ds_message_item.model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ class DSMessageItem {
/// 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 [DSMessageItem] model
/// if the media message is uploading
bool isUploading;

/// Creates a new Design System's [DSMessageItemModel] model
DSMessageItem({
this.id,
required this.date,
Expand All @@ -41,6 +44,7 @@ class DSMessageItem {
this.content,
this.customer,
this.hideMessageDetail,
this.isUploading = false,
});

factory DSMessageItem.fromJson(Map<String, dynamic> json) {
Expand All @@ -53,6 +57,7 @@ class DSMessageItem {
content: json['content'],
status: DSDeliveryReportStatus.unknown.getValue(json['status']),
hideMessageDetail: json['hideMessageDetail'],
isUploading: json['isUploading'] ?? false,
);

if (json.containsKey('customer')) {
Expand Down
53 changes: 53 additions & 0 deletions lib/src/widgets/animations/ds_uploading.widget.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../../themes/colors/ds_colors.theme.dart';
import '../../themes/icons/ds_icons.dart';

class DSUploading extends StatefulWidget {
final double size;
final Color color;

const DSUploading({
super.key,
this.size = 24.0,
this.color = DSColors.neutralLightSnow,
});

@override
State<DSUploading> createState() => _DSUploadingState();
}

class _DSUploadingState extends State<DSUploading> {
final _visible = RxBool(false);

@override
void initState() {
super.initState();
Timer.periodic(
const Duration(seconds: 1),
(timer) {
_visible.value = !_visible.value;
},
);
}

@override
Widget build(BuildContext context) {
return Center(
child: Obx(
() => AnimatedOpacity(
opacity: _visible.value ? 1.0 : 0.0,
duration: const Duration(seconds: 1),
child: Icon(
DSIcons.upload_outline,
color: widget.color,
size: widget.size,
),
),
),
);
}
}
8 changes: 6 additions & 2 deletions lib/src/widgets/chat/audio/ds_audio_player.widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:get/get.dart';
import 'package:just_audio/just_audio.dart';

import '../../../controllers/chat/ds_audio_player.controller.dart';
import '../../../extensions/future.extension.dart';
import '../../../services/ds_auth.service.dart';
import '../../../services/ds_file.service.dart';
import '../../../services/ds_media_format.service.dart';
Expand Down Expand Up @@ -112,7 +113,9 @@ class _DSAudioPlayerState extends State<DSAudioPlayer>
);

try {
await _loadAudio();
await _loadAudio().trueWhile(
_controller.isLoadingAudio,
);

_controller.isInitialized.value = true;
} catch (_) {
Expand Down Expand Up @@ -214,7 +217,8 @@ class _DSAudioPlayerState extends State<DSAudioPlayer>
? _controller.player.play
: () => {},
isLoading: [ProcessingState.loading, ProcessingState.buffering]
.contains(processingState),
.contains(processingState) ||
_controller.isLoadingAudio.value,
color: _controller.isInitialized.value
? widget.controlForegroundColor
: DSColors.contentDisable,
Expand Down
13 changes: 10 additions & 3 deletions lib/src/widgets/chat/ds_delivery_report_icon.widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ class DSDeliveryReportIcon extends StatelessWidget {
const String path = 'assets/images';

switch (deliveryStatus) {
case DSDeliveryReportStatus.accepted:
return _getIcon(
'$path/check.svg',
DSColors.neutralMediumElephant,
);

case DSDeliveryReportStatus.failed:
return DSCaptionSmallText(
'Falha ao enviar mensagem.',
Expand Down Expand Up @@ -67,9 +73,10 @@ class DSDeliveryReportIcon extends StatelessWidget {
);

default:
return _getIcon(
'$path/check.svg',
DSColors.neutralMediumElephant,
return const Icon(
DSIcons.clock_outline,
size: 16,
color: DSColors.contentDefault,
);
}
}
Expand Down
68 changes: 41 additions & 27 deletions lib/src/widgets/chat/ds_file_message_bubble.widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import '../../models/ds_message_bubble_style.model.dart';
import '../../services/ds_auth.service.dart';
import '../../themes/colors/ds_colors.theme.dart';
import '../animations/ds_fading_circle_loading.widget.dart';
import '../animations/ds_uploading.widget.dart';
import '../texts/ds_body_text.widget.dart';
import '../texts/ds_caption_small_text.widget.dart';
import '../utils/ds_file_extension_icon.util.dart';
Expand All @@ -22,6 +23,7 @@ class DSFileMessageBubble extends StatelessWidget {
final List<DSBorderRadius> borderRadius;
final DSMessageBubbleStyle style;
final bool shouldAuthenticate;
final bool isUploading;
final dynamic replyContent;

/// Creates a Design System's [DSMessageBubble] used on files other than image, audio, or video
Expand All @@ -31,34 +33,41 @@ class DSFileMessageBubble extends StatelessWidget {
required this.url,
required this.size,
required this.filename,
this.replyContent,
this.borderRadius = const [DSBorderRadius.all],
this.shouldAuthenticate = false,
DSMessageBubbleStyle? style,
this.isUploading = false,
this.replyContent,
}) : style = style ?? DSMessageBubbleStyle(),
controller = DSFileMessageBubbleController();

@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => controller.openFile(
url: url,
httpHeaders: shouldAuthenticate ? DSAuthService.httpHeaders : null,
),
child: DSMessageBubble(
borderRadius: borderRadius,
replyContent: replyContent,
padding: EdgeInsets.zero,
align: align,
style: style,
child: SizedBox(
height: 80.0,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
_buildIcon(),
_buildText(),
],
onTap: () => !isUploading
? controller.openFile(
url: url,
httpHeaders:
shouldAuthenticate ? DSAuthService.httpHeaders : null,
)
: null,
child: Opacity(
opacity: !isUploading ? 1 : .5,
child: DSMessageBubble(
replyContent: replyContent,
borderRadius: borderRadius,
padding: EdgeInsets.zero,
align: align,
style: style,
child: SizedBox(
height: 80.0,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
_buildIcon(),
_buildText(),
],
),
),
),
),
Expand All @@ -74,15 +83,19 @@ class DSFileMessageBubble extends StatelessWidget {
? const DSFadingCircleLoading(
color: DSColors.neutralDarkRooftop,
)
: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
DSFileExtensionIcon(
filename: filename,
size: 40.0,
: !isUploading
? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
DSFileExtensionIcon(
filename: filename,
size: 40.0,
),
],
)
: const DSUploading(
color: DSColors.neutralDarkRooftop,
),
],
),
),
);
}
Expand All @@ -108,6 +121,7 @@ class DSFileMessageBubble extends StatelessWidget {
filename,
color: color,
textAlign: TextAlign.center,
isSelectable: true,
shouldLinkify: false,
),
Visibility(
Expand Down
63 changes: 29 additions & 34 deletions lib/src/widgets/chat/ds_image_message_bubble.widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import '../../enums/ds_border_radius.enum.dart';
import '../../models/ds_document_select.model.dart';
import '../../models/ds_message_bubble_style.model.dart';
import '../../themes/colors/ds_colors.theme.dart';
import '../../utils/ds_utils.util.dart';
import '../texts/ds_caption_text.widget.dart';
import '../utils/ds_circular_progress.widget.dart';
import '../utils/ds_expanded_image.widget.dart';
Expand All @@ -30,11 +31,10 @@ class DSImageMessageBubble extends StatefulWidget {
this.showSelect = false,
this.onSelected,
this.onOpenLink,
this.replyContent,
this.shouldAuthenticate = false,
this.mediaType,
this.imageMaxHeight,
this.imageMinHeight,
this.isUploading = false,
this.replyContent,
}) : style = style ?? DSMessageBubbleStyle();

final DSAlign align;
Expand All @@ -45,16 +45,15 @@ class DSImageMessageBubble extends StatefulWidget {
final String? text;
final String appBarText;
final Uri? appBarPhotoUri;
final dynamic replyContent;
final DSMessageBubbleStyle style;
final List<DSDocumentSelectOption> selectOptions;
final bool showSelect;
final void Function(String, Map<String, dynamic>)? onSelected;
final void Function(Map<String, dynamic>)? onOpenLink;
final bool shouldAuthenticate;
final String? mediaType;
final double? imageMaxHeight;
final double? imageMinHeight;
final bool isUploading;
final dynamic replyContent;

@override
State<StatefulWidget> createState() => _DSImageMessageBubbleState();
Expand Down Expand Up @@ -84,10 +83,10 @@ class _DSImageMessageBubbleState extends State<DSImageMessageBubble>
: DSColors.neutralLightSnow;

return DSMessageBubble(
defaultMaxSize: 360.0,
replyContent: widget.replyContent,
defaultMaxSize: DSUtils.bubbleMinSize,
shouldUseDefaultSize: true,
align: widget.align,
replyContent: widget.replyContent,
borderRadius: widget.borderRadius,
padding: EdgeInsets.zero,
hasSpacer: widget.hasSpacer,
Expand All @@ -101,32 +100,28 @@ class _DSImageMessageBubbleState extends State<DSImageMessageBubble>
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Obx(
() => _controller.localPath.value != null
? DSExpandedImage(
appBarText: widget.appBarText,
appBarPhotoUri: widget.appBarPhotoUri,
url: _controller.localPath.value!,
maxHeight: widget.imageMaxHeight != null
? widget.imageMaxHeight!
: widget.showSelect
? 200.0
: double.infinity,
minHeight: widget.imageMinHeight != null
? widget.imageMinHeight!
: widget.showSelect
? 200.0
: 0.0,
align: widget.align,
style: widget.style,
isLoading: false,
shouldAuthenticate: widget.shouldAuthenticate,
)
: DSCircularProgress(
currentProgress: _controller.downloadProgress,
maximumProgress: _controller.maximumProgress,
foregroundColor: foregroundColor,
),
SizedBox(
width: DSUtils.bubbleMinSize,
height: 200,
child: Obx(
() => _controller.localPath.value != null
? DSExpandedImage(
width: DSUtils.bubbleMinSize,
appBarText: widget.appBarText,
appBarPhotoUri: widget.appBarPhotoUri,
url: _controller.localPath.value!,
align: widget.align,
style: widget.style,
isLoading: false,
shouldAuthenticate: widget.shouldAuthenticate,
isUploading: widget.isUploading,
)
: DSCircularProgress(
currentProgress: _controller.downloadProgress,
maximumProgress: _controller.maximumProgress,
foregroundColor: foregroundColor,
),
),
),
if ((widget.title?.isNotEmpty ?? false) ||
(widget.text?.isNotEmpty ?? false))
Expand Down
Loading

0 comments on commit f7cd019

Please sign in to comment.