TF-78 Create action bar and context menu when multiple selected email

This commit is contained in:
dab246
2021-09-15 10:05:27 +07:00
committed by Dat H. Pham
parent 59ab5265fd
commit 161eed5d72
21 changed files with 980 additions and 66 deletions
+3
View File
@@ -26,6 +26,9 @@ export 'presentation/views/button/button_builder.dart';
export 'presentation/views/image/avatar_builder.dart';
export 'presentation/views/list/sliver_grid_delegate_fixed_height.dart';
export 'presentation/views/text/text_form_field_builder.dart';
export 'presentation/views/image/icon_builder.dart';
export 'presentation/views/context_menu/context_menu_action_builder.dart';
export 'presentation/views/context_menu/context_menu_builder.dart';
// Resources
export 'presentation/resources/assets_paths.dart';
@@ -36,6 +36,7 @@ class ImagePaths {
String get icComposerMenu => _getImagePath('ic_composer_menu.svg');
String get icComposerFileShare => _getImagePath('ic_composer_file_share.svg');
String get icExpandAddress => _getImagePath('ic_expand_address.svg');
String get icSelected => _getImagePath('ic_selected.svg');
String _getImagePath(String imageName) {
return AssetsPaths.images + imageName;
@@ -0,0 +1,31 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:meta/meta.dart';
typedef OnContextMenuActionClick<T> = void Function(T data);
abstract class ContextMenuActionBuilder<T> {
@protected final Key key;
@protected final SvgPicture actionIcon;
@protected final String actionName;
@protected OnContextMenuActionClick<T>? onContextMenuActionClick;
ContextMenuActionBuilder(
this.key,
this.actionIcon,
this.actionName);
void onActionClick(OnContextMenuActionClick<T> onContextMenuActionClick) {
this.onContextMenuActionClick = onContextMenuActionClick;
}
TextStyle actionTextStyle() {
return TextStyle(
fontSize: 15,
color: AppColor.nameUserColor);
}
Widget build();
}
@@ -0,0 +1,100 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
typedef OnCloseContextMenuAction = void Function();
class ContextMenuBuilder {
final BuildContext _context;
final List<Widget> _actionTiles = [];
final bool areTilesHorizontal;
Widget? _header;
Widget? _footer;
OnCloseContextMenuAction? _onCloseContextMenuAction;
ContextMenuBuilder(
this._context,
{
this.areTilesHorizontal = false
}
);
void addTiles(List<Widget> tiles) {
_actionTiles.addAll(tiles);
}
void addHeader(Widget header) {
_header = header;
}
void addFooter(Widget footer) {
_footer = footer;
}
void addOnCloseContextMenuAction(OnCloseContextMenuAction onCloseContextMenuAction) {
_onCloseContextMenuAction = onCloseContextMenuAction;
}
RoundedRectangleBorder _shape() {
return RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0)));
}
BoxDecoration _decoration(BuildContext context) {
return BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(20.0),
topRight: const Radius.circular(20.0)));
}
void build() {
Get.bottomSheet(
GestureDetector(
onTap: () {
if (_onCloseContextMenuAction != null) {
_onCloseContextMenuAction!();
}},
child: SingleChildScrollView(
child: Container(
margin: EdgeInsets.zero,
decoration: _decoration(_context),
child: GestureDetector(
onTap: () => {},
child: Wrap(
children: [
_header ?? SizedBox.shrink(),
Divider(),
areTilesHorizontal
? Row(children: [
..._actionTiles,
_actionTiles.isNotEmpty && _footer != null ? Divider() : SizedBox.shrink()
])
: Column(children: [
..._actionTiles,
_actionTiles.isNotEmpty && _footer != null ? Divider() : SizedBox.shrink()
]),
_footer != null
? Padding(
padding: EdgeInsets.only(bottom: 10.0),
child: Wrap(children: [_footer ?? SizedBox.shrink()]))
: SizedBox.shrink(),
],
),
),
),
),
),
useRootNavigator: true,
shape: _shape(),
isScrollControlled: true,
enableDrag: false,
backgroundColor: Colors.transparent
);
}
}
@@ -2,12 +2,15 @@ import 'package:core/presentation/extensions/color_extension.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
typedef OnTapAvatarActionClick = void Function();
class AvatarBuilder {
Key? _key;
String? _text;
double? _size;
String? _iconStatus;
Color? _bgColor;
OnTapAvatarActionClick? _onTapAvatarActionClick;
AvatarBuilder key(Key key) {
_key = key;
@@ -34,31 +37,41 @@ class AvatarBuilder {
return this;
}
AvatarBuilder addOnTapActionClick(OnTapAvatarActionClick onTapAvatarActionClick) {
_onTapAvatarActionClick = onTapAvatarActionClick;
return this;
}
Widget build() {
return Container(
key: _key,
width: _size ?? 40,
height: _size ?? 40,
alignment: Alignment.center,
child: Stack(
children: [
Container(
width: _size ?? 40,
height: _size ?? 40,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular((_size ?? 40) / 2),
border: Border.all(color: Colors.white),
color: _bgColor ?? AppColor.avatarColor),
child: Text(
'${_text ?? ''}',
style: TextStyle(fontSize: 20, color: AppColor.avatarTextColor, fontWeight: FontWeight.w500))),
if (_iconStatus != null && _iconStatus!.isNotEmpty)
Align(
child: SvgPicture.asset(_iconStatus!, width: 12, height: 12, fit: BoxFit.fill),
alignment: Alignment.bottomRight)
],
)
return GestureDetector(
onTap: () {
if (_onTapAvatarActionClick != null) {
_onTapAvatarActionClick!();
}},
child: Container(
key: _key,
width: _size ?? 40,
height: _size ?? 40,
alignment: Alignment.center,
child: Stack(
children: [
Container(
width: _size ?? 40,
height: _size ?? 40,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular((_size ?? 40) / 2),
border: Border.all(color: Colors.white),
color: _bgColor ?? AppColor.avatarColor),
child: Text(
'${_text ?? ''}',
style: TextStyle(fontSize: 20, color: AppColor.avatarTextColor, fontWeight: FontWeight.w500))),
if (_iconStatus != null && _iconStatus!.isNotEmpty)
Align(
child: SvgPicture.asset(_iconStatus!, width: 12, height: 12, fit: BoxFit.fill),
alignment: Alignment.bottomRight)
],
)),
);
}
}
@@ -0,0 +1,44 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
typedef OnPressIconActionClick = void Function();
class IconBuilder {
Key? _key;
double? _size;
String? _icon;
OnPressIconActionClick? _onPressIconActionClick;
IconBuilder(this._icon);
void key(Key key) {
_key = key;
}
void size(double size) {
_size = size;
}
void addOnTapActionClick(OnPressIconActionClick onPressIconActionClick) {
_onPressIconActionClick = onPressIconActionClick;
}
Widget build() {
return Container(
key: _key,
width: _size ?? 40,
height: _size ?? 40,
alignment: Alignment.center,
padding: EdgeInsets.all(3),
child: IconButton(
padding: EdgeInsets.zero,
iconSize: _size ?? 40,
icon: SvgPicture.asset(_icon!, width: _size ?? 40, height: _size ?? 40, fit: BoxFit.fill),
onPressed: () => {
if (_onPressIconActionClick != null) {
_onPressIconActionClick!()
}
})
);
}
}
+3
View File
@@ -50,6 +50,9 @@ dependencies:
# sqflite
sqflite: 2.0.0+4
# GetX
get: 4.1.4
dev_dependencies:
flutter_test:
sdk: flutter