TF-2116 Create AttachmentComposer widget and style
(cherry picked from commit 8245f079b4ca19950c32dd7386d4d1d213b53172)
This commit is contained in:
@@ -216,6 +216,8 @@ extension AppColor on Color {
|
|||||||
static const colorRichButtonComposer = Color(0xFFAEAEC0);
|
static const colorRichButtonComposer = Color(0xFFAEAEC0);
|
||||||
static const colorMobileRichButtonComposer = Color(0xFF8C9CAF);
|
static const colorMobileRichButtonComposer = Color(0xFF8C9CAF);
|
||||||
static const colorSelected = Color(0xFFE3F1FF);
|
static const colorSelected = Color(0xFFE3F1FF);
|
||||||
|
static const colorAttachmentBorder = Color(0xFFE5ECF3);
|
||||||
|
static const colorProgressLoadingBackground = Color(0xFFE3F1FF);
|
||||||
|
|
||||||
static const mapGradientColor = [
|
static const mapGradientColor = [
|
||||||
[Color(0xFF21D4FD), Color(0xFFB721FF)],
|
[Color(0xFF21D4FD), Color(0xFFB721FF)],
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class AttachmentComposerWidgetStyle {
|
||||||
|
static const double maxHeight = 150;
|
||||||
|
static const double listItemSpace = 8;
|
||||||
|
|
||||||
|
static const Color backgroundColor = Colors.white;
|
||||||
|
|
||||||
|
static const EdgeInsetsGeometry listItemPadding = EdgeInsetsDirectional.symmetric(vertical: 8, horizontal: 16);
|
||||||
|
|
||||||
|
static const List<BoxShadow> shadow = [
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColor.colorShadowBgContentEmail,
|
||||||
|
blurRadius: 24
|
||||||
|
),
|
||||||
|
BoxShadow(
|
||||||
|
color: AppColor.colorShadowBgContentEmail,
|
||||||
|
blurRadius: 2
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class AttachmentHeaderComposerWidgetStyle {
|
||||||
|
static const double space = 8;
|
||||||
|
static const double iconSize = 20;
|
||||||
|
static const double sizeLabelRadius = 12;
|
||||||
|
|
||||||
|
static const Color iconColor = AppColor.colorLabelComposer;
|
||||||
|
static const Color sizeLabelBackground = AppColor.primaryColor;
|
||||||
|
static const Color borderColor = AppColor.colorLineComposer;
|
||||||
|
|
||||||
|
static const EdgeInsetsGeometry sizeLabelPadding = EdgeInsetsDirectional.symmetric(horizontal: 5, vertical: 2);
|
||||||
|
static const EdgeInsetsGeometry padding = EdgeInsetsDirectional.all(8);
|
||||||
|
|
||||||
|
static const TextStyle labelTextSize = TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
color: AppColor.colorLabelComposer,
|
||||||
|
fontWeight: FontWeight.w500
|
||||||
|
);
|
||||||
|
static const TextStyle sizeLabelTextSize = TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Colors.white,
|
||||||
|
fontWeight: FontWeight.w500
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class AttachmentItemComposerWidgetStyle {
|
||||||
|
static const double radius = 8;
|
||||||
|
static const double iconSize = 20;
|
||||||
|
static const double space = 8;
|
||||||
|
static const double deleteIconSize = 18;
|
||||||
|
static const double deleteIconRadius = 10;
|
||||||
|
static const double width = 260;
|
||||||
|
|
||||||
|
static const Color borderColor = AppColor.colorAttachmentBorder;
|
||||||
|
static const Color backgroundColor = Colors.white;
|
||||||
|
static const Color deleteIconColor = AppColor.colorRichButtonComposer;
|
||||||
|
|
||||||
|
static const EdgeInsetsGeometry padding = EdgeInsetsDirectional.all(8);
|
||||||
|
static const EdgeInsetsGeometry deleteIconPadding = EdgeInsetsDirectional.all(3);
|
||||||
|
static const EdgeInsetsGeometry progressLoadingPadding = EdgeInsetsDirectional.only(top: 8);
|
||||||
|
|
||||||
|
static const TextStyle labelTextStyle = TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Colors.black,
|
||||||
|
fontWeight: FontWeight.w500
|
||||||
|
);
|
||||||
|
static const TextStyle dotsLabelTextStyle = TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Colors.black,
|
||||||
|
fontWeight: FontWeight.w500
|
||||||
|
);
|
||||||
|
static const TextStyle sizeLabelTextStyle = TextStyle(
|
||||||
|
fontSize: 11,
|
||||||
|
color: AppColor.colorLabelComposer,
|
||||||
|
fontWeight: FontWeight.w500
|
||||||
|
);
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class AttachmentProgressLoadingComposerWidgetStyle {
|
||||||
|
static const double height = 2;
|
||||||
|
static const double radius = 1;
|
||||||
|
|
||||||
|
static const Color backgroundColor = AppColor.colorProgressLoadingBackground;
|
||||||
|
static const Color progressColor = AppColor.primaryColor;
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/styles/attachment_composer_widget_style.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/widgets/attachment_item_composer_widget.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/widgets/attachment_header_composer_widget.dart';
|
||||||
|
import 'package:tmail_ui_user/features/upload/presentation/model/upload_file_state.dart';
|
||||||
|
|
||||||
|
typedef OnToggleExpandAttachmentAction = void Function(bool isCollapsed);
|
||||||
|
|
||||||
|
class AttachmentComposerWidget extends StatefulWidget {
|
||||||
|
|
||||||
|
final List<UploadFileState> listFileUploaded;
|
||||||
|
final bool isCollapsed;
|
||||||
|
final OnDeleteAttachmentAction onDeleteAttachmentAction;
|
||||||
|
final OnToggleExpandAttachmentAction onToggleExpandAttachmentAction;
|
||||||
|
|
||||||
|
const AttachmentComposerWidget({
|
||||||
|
super.key,
|
||||||
|
required this.listFileUploaded,
|
||||||
|
required this.isCollapsed,
|
||||||
|
required this.onDeleteAttachmentAction,
|
||||||
|
required this.onToggleExpandAttachmentAction,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AttachmentComposerWidget> createState() => _AttachmentComposerWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AttachmentComposerWidgetState extends State<AttachmentComposerWidget> {
|
||||||
|
|
||||||
|
bool _isCollapsed = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_isCollapsed = widget.isCollapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: AttachmentComposerWidgetStyle.backgroundColor,
|
||||||
|
boxShadow: AttachmentComposerWidgetStyle.shadow
|
||||||
|
),
|
||||||
|
width: double.infinity,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
AttachmentHeaderComposerWidget(
|
||||||
|
listFileUploaded: widget.listFileUploaded,
|
||||||
|
isCollapsed: _isCollapsed,
|
||||||
|
onToggleExpandAction: (isCollapsed) {
|
||||||
|
setState(() => _isCollapsed = !isCollapsed);
|
||||||
|
widget.onToggleExpandAttachmentAction(!isCollapsed);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
if (!_isCollapsed)
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: AttachmentComposerWidgetStyle.listItemPadding,
|
||||||
|
constraints: const BoxConstraints(maxHeight: AttachmentComposerWidgetStyle.maxHeight),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Wrap(
|
||||||
|
spacing: AttachmentComposerWidgetStyle.listItemSpace,
|
||||||
|
runSpacing: AttachmentComposerWidgetStyle.listItemSpace,
|
||||||
|
children: widget.listFileUploaded
|
||||||
|
.map((file) => AttachmentItemComposerWidget(
|
||||||
|
fileState: file,
|
||||||
|
onDeleteAttachmentAction: widget.onDeleteAttachmentAction
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
|
|
||||||
import 'package:core/presentation/extensions/color_extension.dart';
|
|
||||||
import 'package:core/presentation/resources/image_paths.dart';
|
|
||||||
import 'package:core/presentation/utils/style_utils.dart';
|
|
||||||
import 'package:core/presentation/views/button/icon_button_web.dart';
|
|
||||||
import 'package:core/utils/direction_utils.dart';
|
|
||||||
import 'package:core/utils/platform_info.dart';
|
|
||||||
import 'package:extended_text/extended_text.dart';
|
|
||||||
import 'package:filesize/filesize.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
|
|
||||||
import 'package:tmail_ui_user/features/upload/presentation/model/upload_file_state.dart';
|
|
||||||
import 'package:tmail_ui_user/features/upload/presentation/model/upload_file_status.dart';
|
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
|
||||||
|
|
||||||
typedef OnDeleteAttachmentAction = void Function(UploadFileState fileState);
|
|
||||||
|
|
||||||
class AttachmentFileComposerBuilder extends StatelessWidget with AppLoaderMixin {
|
|
||||||
|
|
||||||
final _imagePaths = Get.find<ImagePaths>();
|
|
||||||
|
|
||||||
final UploadFileState fileState;
|
|
||||||
final double? maxWidth;
|
|
||||||
final EdgeInsetsGeometry? itemMargin;
|
|
||||||
final OnDeleteAttachmentAction? onDeleteAttachmentAction;
|
|
||||||
final Widget? buttonAction;
|
|
||||||
|
|
||||||
AttachmentFileComposerBuilder(this.fileState, {
|
|
||||||
super.key,
|
|
||||||
this.maxWidth,
|
|
||||||
this.itemMargin,
|
|
||||||
this.buttonAction,
|
|
||||||
this.onDeleteAttachmentAction,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Theme(
|
|
||||||
data: ThemeData(
|
|
||||||
splashColor: Colors.transparent ,
|
|
||||||
highlightColor: Colors.transparent),
|
|
||||||
child: Container(
|
|
||||||
margin: itemMargin ?? EdgeInsets.zero,
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
alignment: Alignment.center,
|
|
||||||
width: maxWidth,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
border: Border.all(color: AppColor.colorInputBorderCreateMailbox),
|
|
||||||
color: Colors.white),
|
|
||||||
child: Stack(children: [
|
|
||||||
ListTile(
|
|
||||||
contentPadding: EdgeInsets.zero,
|
|
||||||
focusColor: AppColor.primaryColor,
|
|
||||||
hoverColor: AppColor.primaryColor,
|
|
||||||
onTap: () {},
|
|
||||||
leading: Padding(
|
|
||||||
padding: const EdgeInsetsDirectional.only(
|
|
||||||
start: 8,
|
|
||||||
bottom: PlatformInfo.isWeb ? 6 : 14
|
|
||||||
),
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
fileState.getIcon(_imagePaths),
|
|
||||||
width: 40,
|
|
||||||
height: 40,
|
|
||||||
fit: BoxFit.fill),
|
|
||||||
),
|
|
||||||
title: Transform(
|
|
||||||
transform: Matrix4.translationValues(
|
|
||||||
DirectionUtils.isDirectionRTLByLanguage(context) ? 0.0 : (PlatformInfo.isWeb ? 0.0 : -8.0),
|
|
||||||
PlatformInfo.isWeb ? -8.0 : -10.0,
|
|
||||||
0.0),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsetsDirectional.only(end: PlatformInfo.isWeb ? 20 : 16),
|
|
||||||
child: ExtendedText(
|
|
||||||
fileState.fileName,
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: CommonTextStyle.defaultTextOverFlow,
|
|
||||||
softWrap: CommonTextStyle.defaultSoftWrap,
|
|
||||||
overflowWidget: TextOverflowWidget(
|
|
||||||
position: Directionality.maybeOf(context) == TextDirection.rtl
|
|
||||||
? TextOverflowPosition.start
|
|
||||||
: TextOverflowPosition.end,
|
|
||||||
child: const Text(
|
|
||||||
'...',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
color: Colors.black,
|
|
||||||
fontWeight: FontWeight.w500
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
color: Colors.black,
|
|
||||||
fontWeight: FontWeight.w500
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
),
|
|
||||||
subtitle: fileState.fileSize != 0
|
|
||||||
? Transform(
|
|
||||||
transform: Matrix4.translationValues(
|
|
||||||
DirectionUtils.isDirectionRTLByLanguage(context) ? 0.0 : PlatformInfo.isWeb ? 0.0 : -8.0,
|
|
||||||
PlatformInfo.isWeb ? -8.0 : -10.0,
|
|
||||||
0.0),
|
|
||||||
child: Text(
|
|
||||||
filesize(fileState.fileSize),
|
|
||||||
maxLines: 1,
|
|
||||||
softWrap: CommonTextStyle.defaultSoftWrap,
|
|
||||||
overflow: CommonTextStyle.defaultTextOverFlow,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.normal,
|
|
||||||
color: AppColor.colorContentEmail)))
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
PositionedDirectional(
|
|
||||||
end: PlatformInfo.isWeb ? -5 : -12,
|
|
||||||
top: PlatformInfo.isWeb ? -5 : -12,
|
|
||||||
child: buildIconWeb(
|
|
||||||
icon: SvgPicture.asset(_imagePaths.icDeleteAttachment, fit: BoxFit.fill),
|
|
||||||
tooltip: AppLocalizations.of(context).delete,
|
|
||||||
onTap: () {
|
|
||||||
if (onDeleteAttachmentAction != null) {
|
|
||||||
onDeleteAttachmentAction!.call(fileState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
),
|
|
||||||
Align(alignment: AlignmentDirectional.bottomCenter, child: _progressLoading),
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget get _progressLoading {
|
|
||||||
switch(fileState.uploadStatus) {
|
|
||||||
case UploadFileStatus.waiting:
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 8, right: 8, top: 50),
|
|
||||||
child: horizontalLoadingWidget);
|
|
||||||
case UploadFileStatus.uploading:
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.only(top: 50),
|
|
||||||
child: horizontalPercentLoadingWidget(fileState.percentUploading));
|
|
||||||
case UploadFileStatus.uploadFailed:
|
|
||||||
case UploadFileStatus.succeed:
|
|
||||||
return const SizedBox.shrink();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
import 'package:core/presentation/resources/image_paths.dart';
|
||||||
|
import 'package:core/presentation/views/button/tmail_button_widget.dart';
|
||||||
|
import 'package:filesize/filesize.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/styles/attachment_header_composer_widget_style.dart';
|
||||||
|
import 'package:tmail_ui_user/features/upload/presentation/extensions/list_upload_file_state_extension.dart';
|
||||||
|
import 'package:tmail_ui_user/features/upload/presentation/model/upload_file_state.dart';
|
||||||
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
|
|
||||||
|
typedef OnToggleExpandAttachmentViewAction = Function(bool isCollapsed);
|
||||||
|
|
||||||
|
class AttachmentHeaderComposerWidget extends StatelessWidget {
|
||||||
|
|
||||||
|
final List<UploadFileState> listFileUploaded;
|
||||||
|
final bool isCollapsed;
|
||||||
|
final OnToggleExpandAttachmentViewAction onToggleExpandAction;
|
||||||
|
|
||||||
|
final _imagePaths = Get.find<ImagePaths>();
|
||||||
|
|
||||||
|
AttachmentHeaderComposerWidget({
|
||||||
|
super.key,
|
||||||
|
required this.listFileUploaded,
|
||||||
|
required this.isCollapsed,
|
||||||
|
required this.onToggleExpandAction,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () => onToggleExpandAction.call(isCollapsed),
|
||||||
|
child: Container(
|
||||||
|
padding: AttachmentHeaderComposerWidgetStyle.padding,
|
||||||
|
decoration: isCollapsed
|
||||||
|
? null
|
||||||
|
: const BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(
|
||||||
|
color: AttachmentHeaderComposerWidgetStyle.borderColor,
|
||||||
|
width: 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
TMailButtonWidget.fromIcon(
|
||||||
|
icon: isCollapsed
|
||||||
|
? _imagePaths.icArrowRight
|
||||||
|
: _imagePaths.icArrowBottom,
|
||||||
|
iconSize: AttachmentHeaderComposerWidgetStyle.iconSize,
|
||||||
|
iconColor: AttachmentHeaderComposerWidgetStyle.iconColor,
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
onTapActionCallback: () => onToggleExpandAction.call(isCollapsed),
|
||||||
|
),
|
||||||
|
const SizedBox(width: AttachmentHeaderComposerWidgetStyle.space / 2),
|
||||||
|
Text(
|
||||||
|
'${listFileUploaded.length} ${AppLocalizations.of(context).attachments}',
|
||||||
|
style: AttachmentHeaderComposerWidgetStyle.labelTextSize
|
||||||
|
),
|
||||||
|
const SizedBox(width: AttachmentHeaderComposerWidgetStyle.space),
|
||||||
|
Container(
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
color: AttachmentHeaderComposerWidgetStyle.sizeLabelBackground,
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(AttachmentHeaderComposerWidgetStyle.sizeLabelRadius))
|
||||||
|
),
|
||||||
|
padding: AttachmentHeaderComposerWidgetStyle.sizeLabelPadding,
|
||||||
|
child: Text(
|
||||||
|
filesize(listFileUploaded.totalSize, 0),
|
||||||
|
style: AttachmentHeaderComposerWidgetStyle.sizeLabelTextSize,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
import 'package:core/presentation/resources/image_paths.dart';
|
||||||
|
import 'package:core/presentation/views/button/tmail_button_widget.dart';
|
||||||
|
import 'package:extended_text/extended_text.dart';
|
||||||
|
import 'package:filesize/filesize.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/styles/attachment_item_composer_widget_style.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/widgets/attachment_progress_loading_composer_widget.dart';
|
||||||
|
import 'package:tmail_ui_user/features/upload/presentation/model/upload_file_state.dart';
|
||||||
|
|
||||||
|
typedef OnDeleteAttachmentAction = void Function(UploadFileState fileState);
|
||||||
|
|
||||||
|
class AttachmentItemComposerWidget extends StatelessWidget with AppLoaderMixin {
|
||||||
|
|
||||||
|
final _imagePaths = Get.find<ImagePaths>();
|
||||||
|
|
||||||
|
final UploadFileState fileState;
|
||||||
|
final double? maxWidth;
|
||||||
|
final EdgeInsetsGeometry? itemMargin;
|
||||||
|
final OnDeleteAttachmentAction? onDeleteAttachmentAction;
|
||||||
|
final Widget? buttonAction;
|
||||||
|
|
||||||
|
AttachmentItemComposerWidget({
|
||||||
|
super.key,
|
||||||
|
required this.fileState,
|
||||||
|
this.maxWidth,
|
||||||
|
this.itemMargin,
|
||||||
|
this.buttonAction,
|
||||||
|
this.onDeleteAttachmentAction,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(AttachmentItemComposerWidgetStyle.radius)),
|
||||||
|
border: Border.all(color: AttachmentItemComposerWidgetStyle.borderColor),
|
||||||
|
color: AttachmentItemComposerWidgetStyle.backgroundColor
|
||||||
|
),
|
||||||
|
width: AttachmentItemComposerWidgetStyle.width,
|
||||||
|
padding: AttachmentItemComposerWidgetStyle.padding,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset(
|
||||||
|
fileState.getIcon(_imagePaths),
|
||||||
|
width: AttachmentItemComposerWidgetStyle.iconSize,
|
||||||
|
height: AttachmentItemComposerWidgetStyle.iconSize,
|
||||||
|
fit: BoxFit.fill
|
||||||
|
),
|
||||||
|
const SizedBox(width: AttachmentItemComposerWidgetStyle.space),
|
||||||
|
Expanded(
|
||||||
|
child: ExtendedText(
|
||||||
|
fileState.fileName,
|
||||||
|
maxLines: 1,
|
||||||
|
overflowWidget: const TextOverflowWidget(
|
||||||
|
position: TextOverflowPosition.middle,
|
||||||
|
child: Text(
|
||||||
|
'...',
|
||||||
|
style: AttachmentItemComposerWidgetStyle.dotsLabelTextStyle,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
style: AttachmentItemComposerWidgetStyle.labelTextStyle,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: AttachmentItemComposerWidgetStyle.space),
|
||||||
|
Text(
|
||||||
|
filesize(fileState.fileSize),
|
||||||
|
style: AttachmentItemComposerWidgetStyle.sizeLabelTextStyle
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
AttachmentProgressLoadingComposerWidget(
|
||||||
|
fileState: fileState,
|
||||||
|
padding: AttachmentItemComposerWidgetStyle.progressLoadingPadding,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: AttachmentItemComposerWidgetStyle.space),
|
||||||
|
TMailButtonWidget.fromIcon(
|
||||||
|
icon: _imagePaths.icCancel,
|
||||||
|
iconSize: AttachmentItemComposerWidgetStyle.deleteIconSize,
|
||||||
|
borderRadius: AttachmentItemComposerWidgetStyle.deleteIconRadius,
|
||||||
|
padding: AttachmentItemComposerWidgetStyle.deleteIconPadding,
|
||||||
|
iconColor: AttachmentItemComposerWidgetStyle.deleteIconColor,
|
||||||
|
onTapActionCallback: () => onDeleteAttachmentAction?.call(fileState),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+49
@@ -0,0 +1,49 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:percent_indicator/linear_percent_indicator.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/styles/attachment_progress_loading_composer_widget_style.dart';
|
||||||
|
import 'package:tmail_ui_user/features/upload/presentation/model/upload_file_state.dart';
|
||||||
|
import 'package:tmail_ui_user/features/upload/presentation/model/upload_file_status.dart';
|
||||||
|
|
||||||
|
class AttachmentProgressLoadingComposerWidget extends StatelessWidget {
|
||||||
|
|
||||||
|
final UploadFileState fileState;
|
||||||
|
final EdgeInsetsGeometry? padding;
|
||||||
|
|
||||||
|
const AttachmentProgressLoadingComposerWidget({
|
||||||
|
super.key,
|
||||||
|
required this.fileState,
|
||||||
|
this.padding,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
switch (fileState.uploadStatus) {
|
||||||
|
case UploadFileStatus.waiting:
|
||||||
|
return Padding(
|
||||||
|
padding: padding ?? EdgeInsets.zero,
|
||||||
|
child: const LinearProgressIndicator(
|
||||||
|
color: AttachmentProgressLoadingComposerWidgetStyle.progressColor,
|
||||||
|
minHeight: AttachmentProgressLoadingComposerWidgetStyle.height,
|
||||||
|
backgroundColor: AttachmentProgressLoadingComposerWidgetStyle.backgroundColor,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
case UploadFileStatus.uploading:
|
||||||
|
return Padding(
|
||||||
|
padding: padding ?? EdgeInsets.zero,
|
||||||
|
child: LinearPercentIndicator(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
lineHeight:AttachmentProgressLoadingComposerWidgetStyle.height,
|
||||||
|
percent: fileState.percentUploading > 1.0
|
||||||
|
? 1.0
|
||||||
|
: fileState.percentUploading,
|
||||||
|
barRadius: const Radius.circular(AttachmentProgressLoadingComposerWidgetStyle.radius),
|
||||||
|
backgroundColor: AttachmentProgressLoadingComposerWidgetStyle.backgroundColor,
|
||||||
|
progressColor: AttachmentProgressLoadingComposerWidgetStyle.progressColor,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
case UploadFileStatus.uploadFailed:
|
||||||
|
case UploadFileStatus.succeed:
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user