TF-2172 Add DropZone widget

(cherry picked from commit 72f5f04800c1bb56118676b44cf0102ba14ef034)
This commit is contained in:
dab246
2023-10-02 15:07:33 +07:00
committed by Dat H. Pham
parent 20fd8ebdee
commit 5b8c45586b
9 changed files with 148 additions and 1 deletions
@@ -0,0 +1,22 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:flutter/material.dart';
class DropZoneWidgetStyle {
static const double space = 20;
static const double borderWidth = 2;
static const double radius = 16;
static const List<double> dashSize = [6, 3];
static const Color backgroundColor = AppColor.colorDropZoneBackground;
static const Color borderColor = AppColor.colorDropZoneBorder;
static const EdgeInsetsGeometry padding = EdgeInsets.all(20);
static const EdgeInsetsGeometry margin = EdgeInsetsDirectional.symmetric(vertical: 8);
static const TextStyle labelTextStyle = TextStyle(
color: Colors.black,
fontSize: 22,
fontWeight: FontWeight.w600
);
}
@@ -0,0 +1,87 @@
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/utils/app_logger.dart';
import 'package:dotted_border/dotted_border.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:model/email/attachment.dart';
import 'package:tmail_ui_user/features/composer/presentation/styles/web/drop_zone_widget_style.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class DropZoneWidget extends StatefulWidget {
final double? width;
final double? height;
const DropZoneWidget({super.key, this.width, this.height});
@override
State<DropZoneWidget> createState() => _DropZoneWidgetState();
}
class _DropZoneWidgetState extends State<DropZoneWidget> {
final _imagePaths = Get.find<ImagePaths>();
bool _isDragging = false;
@override
Widget build(BuildContext context) {
return DragTarget<Attachment>(
builder: (context, candidateData, rejectedData) {
if (_isDragging) {
return Padding(
padding: DropZoneWidgetStyle.margin,
child: DottedBorder(
borderType: BorderType.RRect,
radius: const Radius.circular(DropZoneWidgetStyle.radius),
color: DropZoneWidgetStyle.borderColor,
strokeWidth: DropZoneWidgetStyle.borderWidth,
dashPattern: DropZoneWidgetStyle.dashSize,
child: Container(
clipBehavior: Clip.antiAlias,
decoration: const ShapeDecoration(
color: DropZoneWidgetStyle.backgroundColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(DropZoneWidgetStyle.radius)),
),
),
width: widget.width,
height: widget.height,
padding: DropZoneWidgetStyle.padding,
alignment: AlignmentDirectional.center,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SvgPicture.asset(_imagePaths.icDropZoneIcon),
const SizedBox(height: DropZoneWidgetStyle.space),
Text(
AppLocalizations.of(context).dropFileHereToAttachThem,
style: DropZoneWidgetStyle.labelTextStyle,
)
]
),
),
),
);
} else {
return SizedBox(width: widget.width, height: widget.height);
}
},
onAccept: (attachment) {
log('_DropZoneWidgetState::build:onAccept: $attachment');
},
onLeave: (attachment) {
if (_isDragging) {
setState(() => _isDragging = false);
}
},
onMove: (details) {
if (!_isDragging) {
setState(() => _isDragging = true);
}
},
);
}
}