TF-4002 Apply new design for folder creation modal on mobile
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||
import 'package:model/model.dart';
|
||||
@@ -14,8 +14,11 @@ import 'package:tmail_ui_user/features/mailbox_creator/domain/model/verification
|
||||
import 'package:tmail_ui_user/features/mailbox_creator/domain/state/verify_name_view_state.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_name_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_creator/presentation/extensions/validator_failure_extension.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/bottom_modal_folder_tree_arguments.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/mailbox_creator_arguments.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/new_mailbox_arguments.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_creator/presentation/widgets/bottom_modal/bottom_modal_folder_tree_list_bindings.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_creator/presentation/widgets/bottom_modal/bottom_modal_folder_tree_list_widget.dart';
|
||||
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
||||
|
||||
class MailboxCreatorController extends BaseController
|
||||
@@ -124,13 +127,20 @@ class MailboxCreatorController extends BaseController
|
||||
void openFolderModal(BuildContext context) {
|
||||
nameInputFocusNode.unfocus();
|
||||
|
||||
if (!responsiveUtils.isMobile(context)) {
|
||||
if (responsiveUtils.isMobile(context)) {
|
||||
_showFolderListBottomModal(context);
|
||||
} else {
|
||||
isFolderModalEnabled.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
void selectMailboxLocation(MailboxNode? mailboxDestination) {
|
||||
isFolderModalEnabled.value = false;
|
||||
void selectMailboxLocation(
|
||||
BuildContext context,
|
||||
MailboxNode? mailboxDestination,
|
||||
) {
|
||||
if (!responsiveUtils.isMobile(context)) {
|
||||
isFolderModalEnabled.value = false;
|
||||
}
|
||||
selectedMailbox.value = mailboxDestination?.item;
|
||||
_createListMailboxNameAsStringInMailboxLocation();
|
||||
}
|
||||
@@ -177,6 +187,41 @@ class MailboxCreatorController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _showFolderListBottomModal(BuildContext context) async {
|
||||
BottomModalFolderTreeListBindings().dependencies();
|
||||
|
||||
final result = await showModalBottomSheet(
|
||||
context: context,
|
||||
showDragHandle: true,
|
||||
useSafeArea: true,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(16.0),
|
||||
topRight: Radius.circular(16.0),
|
||||
),
|
||||
),
|
||||
backgroundColor: Colors.white,
|
||||
routeSettings: RouteSettings(
|
||||
arguments: BottomModalFolderTreeArguments(
|
||||
defaultMailboxTree.value,
|
||||
personalMailboxTree.value,
|
||||
selectedMailbox.value,
|
||||
),
|
||||
),
|
||||
builder: (_) => const BottomModalFolderTreeListWidget(),
|
||||
).whenComplete(BottomModalFolderTreeListBindings().dispose);
|
||||
|
||||
if (result is PresentationMailbox) {
|
||||
if (result.id == MailboxNode.root().item.id) {
|
||||
selectedMailbox.value = null;
|
||||
} else {
|
||||
selectedMailbox.value = result;
|
||||
}
|
||||
_createListMailboxNameAsStringInMailboxLocation();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void closeView() {
|
||||
nameInputFocusNode.unfocus();
|
||||
popBack();
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:math';
|
||||
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/utils/theme_utils.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/base/widget/default_field/default_button_arrow_down_field_widget.dart';
|
||||
@@ -159,10 +160,9 @@ class MailboxCreatorView extends GetWidget<MailboxCreatorController> {
|
||||
defaultTree: controller.defaultMailboxTree.value,
|
||||
personalTree: controller.personalMailboxTree.value,
|
||||
imagePaths: controller.imagePaths,
|
||||
listScrollController:
|
||||
controller.listFolderScrollController,
|
||||
listScrollController: controller.listFolderScrollController,
|
||||
mailboxIdSelected: selectedMailbox?.id,
|
||||
onSelectFolderAction: controller.selectMailboxLocation,
|
||||
onSelectFolderAction: (node) => controller.selectMailboxLocation(context, node),
|
||||
onToggleFolderAction: controller.toggleFolder,
|
||||
)),
|
||||
)
|
||||
@@ -197,6 +197,21 @@ class MailboxCreatorView extends GetWidget<MailboxCreatorController> {
|
||||
),
|
||||
);
|
||||
|
||||
return Center(child: bodyWidget);
|
||||
bodyWidget = Center(child: bodyWidget);
|
||||
|
||||
if (PlatformInfo.isMobile) {
|
||||
bodyWidget = GestureDetector(
|
||||
onTap: controller.closeView,
|
||||
child: Scaffold(
|
||||
backgroundColor: AppColor.blackAlpha20,
|
||||
body: GestureDetector(
|
||||
onTap: controller.nameInputFocusNode.unfocus,
|
||||
child: bodyWidget,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return bodyWidget;
|
||||
}
|
||||
}
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:model/mailbox/presentation_mailbox.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree.dart';
|
||||
|
||||
class BottomModalFolderTreeArguments with EquatableMixin {
|
||||
final MailboxTree personalMailboxTree;
|
||||
final MailboxTree defaultMailboxTree;
|
||||
final PresentationMailbox? selectedMailbox;
|
||||
|
||||
BottomModalFolderTreeArguments(
|
||||
this.defaultMailboxTree,
|
||||
this.personalMailboxTree,
|
||||
this.selectedMailbox,
|
||||
);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
defaultMailboxTree,
|
||||
personalMailboxTree,
|
||||
selectedMailbox,
|
||||
];
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_creator/presentation/widgets/bottom_modal/bottom_modal_folder_tree_list_controller.dart';
|
||||
|
||||
class BottomModalFolderTreeListBindings extends Bindings {
|
||||
@override
|
||||
void dependencies() {
|
||||
Get.lazyPut(() => BottomModalFolderTreeListController());
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
Get.delete<BottomModalFolderTreeListController>();
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||
import 'package:tmail_ui_user/features/base/base_controller.dart';
|
||||
import 'package:tmail_ui_user/features/base/mixin/expand_folder_trigger_scrollable_mixin.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/extensions/expand_mode_extension.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/bottom_modal_folder_tree_arguments.dart';
|
||||
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
||||
|
||||
class BottomModalFolderTreeListController extends BaseController
|
||||
with ExpandFolderTriggerScrollableMixin {
|
||||
final personalMailboxTree = MailboxTree(MailboxNode.root()).obs;
|
||||
final defaultMailboxTree = MailboxTree(MailboxNode.root()).obs;
|
||||
final mailboxIdSelected = Rxn<MailboxId>();
|
||||
|
||||
final ScrollController listFolderScrollController = ScrollController();
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
BottomModalFolderTreeArguments? arguments = Get.arguments;
|
||||
if (arguments != null) {
|
||||
personalMailboxTree.value = arguments.personalMailboxTree;
|
||||
defaultMailboxTree.value = arguments.defaultMailboxTree;
|
||||
mailboxIdSelected.value = arguments.selectedMailbox?.id;
|
||||
}
|
||||
}
|
||||
|
||||
void selectFolderAction(MailboxNode? mailboxNode) {
|
||||
final selectedMailbox = mailboxNode?.item;
|
||||
popBack(result: selectedMailbox);
|
||||
}
|
||||
|
||||
void toggleFolder(MailboxNode selectedMailboxNode, GlobalKey itemKey) {
|
||||
final newExpandMode = selectedMailboxNode.expandMode.toggle();
|
||||
|
||||
if (defaultMailboxTree.value.updateExpandedNode(selectedMailboxNode, newExpandMode) != null) {
|
||||
defaultMailboxTree.refresh();
|
||||
triggerScrollWhenExpandFolder(
|
||||
selectedMailboxNode.expandMode,
|
||||
itemKey,
|
||||
listFolderScrollController,
|
||||
);
|
||||
}
|
||||
|
||||
if (personalMailboxTree.value.updateExpandedNode(selectedMailboxNode, newExpandMode) != null) {
|
||||
personalMailboxTree.refresh();
|
||||
triggerScrollWhenExpandFolder(
|
||||
selectedMailboxNode.expandMode,
|
||||
itemKey,
|
||||
listFolderScrollController,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
listFolderScrollController.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/utils/theme_utils.dart';
|
||||
import 'package:core/presentation/views/list/tree_view.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||
import 'package:model/mailbox/expand_mode.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_displayed.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_node.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/folder_item_widget.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_item_widget.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_creator/presentation/widgets/bottom_modal/bottom_modal_folder_tree_list_controller.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class BottomModalFolderTreeListWidget extends GetWidget<BottomModalFolderTreeListController> {
|
||||
|
||||
const BottomModalFolderTreeListWidget({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget bodyWidget = Container(
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: min(
|
||||
controller.responsiveUtils.getSizeScreenHeight(context) - 32,
|
||||
469,
|
||||
),
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
physics: const ClampingScrollPhysics(),
|
||||
controller: controller.listFolderScrollController,
|
||||
padding: const EdgeInsetsDirectional.all(14),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Obx(() => FolderItemWidget(
|
||||
folderName: AppLocalizations.of(context).personalFolders,
|
||||
imagePaths: controller.imagePaths,
|
||||
isSelected: controller.mailboxIdSelected.value == null,
|
||||
iconColor: AppColor.gray424244.withValues(alpha: 0.72),
|
||||
iconSelected: controller.imagePaths.icChecked,
|
||||
textStyle: ThemeUtils.textStyleInter400.copyWith(
|
||||
color: AppColor.gray424244.withValues(alpha: 0.9),
|
||||
fontSize: 16,
|
||||
height: 21.01 / 16,
|
||||
letterSpacing: -0.15,
|
||||
),
|
||||
onTapAction: () =>
|
||||
controller.selectFolderAction(MailboxNode.root()),
|
||||
)),
|
||||
Obx(() {
|
||||
final defaultTree = controller.defaultMailboxTree.value;
|
||||
if (defaultTree.root.hasChildren()) {
|
||||
return _buildFolderTree(
|
||||
mailboxTree: defaultTree,
|
||||
mailboxIdSelected: controller.mailboxIdSelected.value,
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}),
|
||||
Obx(() {
|
||||
final personalTree = controller.personalMailboxTree.value;
|
||||
if (personalTree.root.hasChildren()) {
|
||||
return _buildFolderTree(
|
||||
mailboxTree: personalTree,
|
||||
mailboxIdSelected: controller.mailboxIdSelected.value,
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (PlatformInfo.isMobile) {
|
||||
return SafeArea(child: bodyWidget);
|
||||
} else {
|
||||
return bodyWidget;
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildFolderTree({
|
||||
required MailboxTree mailboxTree,
|
||||
MailboxId? mailboxIdSelected,
|
||||
}) {
|
||||
return TreeView(
|
||||
children: _buildListChildTileWidget(
|
||||
parentNode: mailboxTree.root,
|
||||
mailboxIdSelected: mailboxIdSelected,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _buildListChildTileWidget({
|
||||
required MailboxNode parentNode,
|
||||
MailboxId? mailboxIdSelected,
|
||||
}) {
|
||||
return parentNode.childrenItems?.map(
|
||||
(mailboxNode) {
|
||||
if (mailboxNode.hasChildren()) {
|
||||
return TreeViewChild(
|
||||
isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND,
|
||||
paddingChild: const EdgeInsetsDirectional.only(start: 14),
|
||||
parent: MailboxItemWidget(
|
||||
mailboxNode: mailboxNode,
|
||||
mailboxIdAlreadySelected: mailboxIdSelected,
|
||||
mailboxDisplayed: MailboxDisplayed.modalFolder,
|
||||
hoverColor: AppColor.blue100,
|
||||
iconColor: AppColor.gray424244.withValues(alpha: 0.72),
|
||||
textStyle: ThemeUtils.textStyleInter400.copyWith(
|
||||
color: AppColor.gray424244.withValues(alpha: 0.9),
|
||||
fontSize: 16,
|
||||
height: 21.01 / 16,
|
||||
letterSpacing: -0.15,
|
||||
),
|
||||
itemHeight: 48,
|
||||
iconSelected: controller.imagePaths.icChecked,
|
||||
onOpenMailboxFolderClick: controller.selectFolderAction,
|
||||
onExpandFolderActionClick: controller.toggleFolder,
|
||||
),
|
||||
children: _buildListChildTileWidget(
|
||||
parentNode: mailboxNode,
|
||||
mailboxIdSelected: mailboxIdSelected,
|
||||
),
|
||||
).build();
|
||||
} else {
|
||||
return MailboxItemWidget(
|
||||
mailboxNode: mailboxNode,
|
||||
mailboxDisplayed: MailboxDisplayed.modalFolder,
|
||||
mailboxIdAlreadySelected: mailboxIdSelected,
|
||||
hoverColor: AppColor.blue100,
|
||||
iconColor: AppColor.gray424244.withValues(alpha: 0.72),
|
||||
textStyle: ThemeUtils.textStyleInter400.copyWith(
|
||||
color: AppColor.gray424244.withValues(alpha: 0.9),
|
||||
fontSize: 16,
|
||||
height: 21.01 / 16,
|
||||
letterSpacing: -0.15,
|
||||
),
|
||||
itemHeight: 48,
|
||||
iconSelected: controller.imagePaths.icChecked,
|
||||
onOpenMailboxFolderClick: controller.selectFolderAction,
|
||||
onExpandFolderActionClick: controller.toggleFolder,
|
||||
);
|
||||
}
|
||||
},
|
||||
).toList() ?? [];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user