TF-4002 Apply new design for folder creation modal on web
This commit is contained in:
@@ -52,24 +52,20 @@ class _TreeViewData extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TreeViewChild {
|
class TreeViewChild {
|
||||||
final BuildContext context;
|
|
||||||
final bool? isExpanded;
|
final bool? isExpanded;
|
||||||
final Widget parent;
|
final Widget parent;
|
||||||
final List<Widget> children;
|
final List<Widget> children;
|
||||||
final VoidCallback? onTap;
|
final VoidCallback? onTap;
|
||||||
final EdgeInsetsGeometry? paddingChild;
|
final EdgeInsetsGeometry? paddingChild;
|
||||||
|
|
||||||
TreeViewChild(
|
TreeViewChild({
|
||||||
this.context,
|
required this.parent,
|
||||||
{
|
required this.children,
|
||||||
required this.parent,
|
this.isExpanded,
|
||||||
required this.children,
|
this.onTap,
|
||||||
this.isExpanded,
|
this.paddingChild,
|
||||||
this.onTap,
|
Key? key,
|
||||||
this.paddingChild,
|
});
|
||||||
Key? key,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
Widget build() {
|
Widget build() {
|
||||||
return Column(
|
return Column(
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import 'package:tmail_ui_user/features/base/action/update_mailbox_properties_act
|
|||||||
import 'package:tmail_ui_user/features/base/action/update_mailbox_properties_action/update_mailbox_total_emails_count_action.dart';
|
import 'package:tmail_ui_user/features/base/action/update_mailbox_properties_action/update_mailbox_total_emails_count_action.dart';
|
||||||
import 'package:tmail_ui_user/features/base/action/update_mailbox_properties_action/update_mailbox_unread_count_action.dart';
|
import 'package:tmail_ui_user/features/base/action/update_mailbox_properties_action/update_mailbox_unread_count_action.dart';
|
||||||
import 'package:tmail_ui_user/features/base/base_controller.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/base/mixin/message_dialog_action_manager.dart';
|
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
|
||||||
import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart';
|
import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subscribe_action_state.dart';
|
import 'package:tmail_ui_user/features/mailbox/domain/model/mailbox_subscribe_action_state.dart';
|
||||||
@@ -55,7 +56,8 @@ typedef MovingMailboxActionCallback = void Function(PresentationMailbox mailboxS
|
|||||||
typedef DeleteMailboxActionCallback = void Function(PresentationMailbox mailbox);
|
typedef DeleteMailboxActionCallback = void Function(PresentationMailbox mailbox);
|
||||||
typedef AllowSubaddressingActionCallback = void Function(MailboxId, Map<String, List<String>?>?, MailboxActions);
|
typedef AllowSubaddressingActionCallback = void Function(MailboxId, Map<String, List<String>?>?, MailboxActions);
|
||||||
|
|
||||||
abstract class BaseMailboxController extends BaseController {
|
abstract class BaseMailboxController extends BaseController
|
||||||
|
with ExpandFolderTriggerScrollableMixin {
|
||||||
final TreeBuilder _treeBuilder;
|
final TreeBuilder _treeBuilder;
|
||||||
final VerifyNameInteractor verifyNameInteractor;
|
final VerifyNameInteractor verifyNameInteractor;
|
||||||
final GetAllMailboxInteractor? getAllMailboxInteractor;
|
final GetAllMailboxInteractor? getAllMailboxInteractor;
|
||||||
@@ -159,44 +161,6 @@ abstract class BaseMailboxController extends BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void triggerScrollWhenExpandFolder(
|
|
||||||
ExpandMode expandMode,
|
|
||||||
GlobalKey itemKey,
|
|
||||||
ScrollController scrollController,
|
|
||||||
) {
|
|
||||||
if (expandMode == ExpandMode.COLLAPSE) return;
|
|
||||||
|
|
||||||
final context = itemKey.currentContext;
|
|
||||||
if (context == null) return;
|
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
_scrollToSelfIfNeeded(context, scrollController);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void _scrollToSelfIfNeeded(
|
|
||||||
BuildContext context,
|
|
||||||
ScrollController scrollController,
|
|
||||||
) {
|
|
||||||
final renderBox = context.findRenderObject() as RenderBox?;
|
|
||||||
if (renderBox == null) return;
|
|
||||||
|
|
||||||
final position = renderBox.localToGlobal(Offset.zero);
|
|
||||||
final screenHeight = MediaQuery.of(context).size.height;
|
|
||||||
const offsetY = 200;
|
|
||||||
final bottomY = position.dy + renderBox.size.height + offsetY;
|
|
||||||
log('BaseMailboxController::_scrollToSelfIfNeeded:position = $position |screenHeight = $screenHeight | bottomY = $bottomY');
|
|
||||||
if (bottomY > screenHeight) {
|
|
||||||
final scrollOffset = scrollController.offset + bottomY - screenHeight + 40;
|
|
||||||
log('BaseMailboxController::_scrollToSelfIfNeeded:scrollOffset = $scrollOffset:');
|
|
||||||
scrollController.animateTo(
|
|
||||||
scrollOffset,
|
|
||||||
duration: const Duration(milliseconds: 300),
|
|
||||||
curve: Curves.easeInOut,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void selectMailboxNode(MailboxNode mailboxNodeSelected) {
|
void selectMailboxNode(MailboxNode mailboxNodeSelected) {
|
||||||
final newSelectMode = mailboxNodeSelected.selectMode == SelectMode.INACTIVE
|
final newSelectMode = mailboxNodeSelected.selectMode == SelectMode.INACTIVE
|
||||||
? SelectMode.ACTIVE
|
? SelectMode.ACTIVE
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import 'package:core/utils/app_logger.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:model/mailbox/expand_mode.dart';
|
||||||
|
|
||||||
|
mixin ExpandFolderTriggerScrollableMixin {
|
||||||
|
void triggerScrollWhenExpandFolder(
|
||||||
|
ExpandMode expandMode,
|
||||||
|
GlobalKey itemKey,
|
||||||
|
ScrollController scrollController,
|
||||||
|
) {
|
||||||
|
if (expandMode == ExpandMode.COLLAPSE) return;
|
||||||
|
|
||||||
|
final context = itemKey.currentContext;
|
||||||
|
if (context == null) return;
|
||||||
|
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
_scrollToSelfIfNeeded(context, scrollController);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _scrollToSelfIfNeeded(
|
||||||
|
BuildContext context,
|
||||||
|
ScrollController scrollController,
|
||||||
|
) {
|
||||||
|
final renderBox = context.findRenderObject() as RenderBox?;
|
||||||
|
if (renderBox == null) return;
|
||||||
|
|
||||||
|
final position = renderBox.localToGlobal(Offset.zero);
|
||||||
|
final screenHeight = MediaQuery.of(context).size.height;
|
||||||
|
const offsetY = 200;
|
||||||
|
final bottomY = position.dy + renderBox.size.height + offsetY;
|
||||||
|
log('$runtimeType::_scrollToSelfIfNeeded:position = $position |screenHeight = $screenHeight | bottomY = $bottomY');
|
||||||
|
if (bottomY > screenHeight) {
|
||||||
|
final scrollOffset =
|
||||||
|
scrollController.offset + bottomY - screenHeight + 40;
|
||||||
|
log('$runtimeType::_scrollToSelfIfNeeded:scrollOffset = $scrollOffset:');
|
||||||
|
scrollController.animateTo(
|
||||||
|
scrollOffset,
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,12 +7,14 @@ class DefaultButtonArrowDownFieldWidget extends StatelessWidget {
|
|||||||
final String text;
|
final String text;
|
||||||
final String iconArrowDown;
|
final String iconArrowDown;
|
||||||
final VoidCallback onTap;
|
final VoidCallback onTap;
|
||||||
|
final Widget? icon;
|
||||||
|
|
||||||
const DefaultButtonArrowDownFieldWidget({
|
const DefaultButtonArrowDownFieldWidget({
|
||||||
super.key,
|
super.key,
|
||||||
required this.text,
|
required this.text,
|
||||||
required this.iconArrowDown,
|
required this.iconArrowDown,
|
||||||
required this.onTap,
|
required this.onTap,
|
||||||
|
this.icon,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -35,6 +37,7 @@ class DefaultButtonArrowDownFieldWidget extends StatelessWidget {
|
|||||||
padding: const EdgeInsetsDirectional.only(start: 12, end: 8),
|
padding: const EdgeInsetsDirectional.only(start: 12, end: 8),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
|
if (icon != null) icon!,
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
text,
|
text,
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:core/presentation/views/dialog/confirm_dialog_button.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class ModalListActionButtonWidget extends StatelessWidget {
|
||||||
|
final String positiveLabel;
|
||||||
|
final String negativeLabel;
|
||||||
|
final VoidCallback onNegativeAction;
|
||||||
|
final VoidCallback onPositiveAction;
|
||||||
|
final EdgeInsetsGeometry? padding;
|
||||||
|
|
||||||
|
const ModalListActionButtonWidget({
|
||||||
|
super.key,
|
||||||
|
required this.positiveLabel,
|
||||||
|
required this.negativeLabel,
|
||||||
|
required this.onPositiveAction,
|
||||||
|
required this.onNegativeAction,
|
||||||
|
this.padding,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
Widget negativeButton = Container(
|
||||||
|
constraints: const BoxConstraints(minWidth: 67),
|
||||||
|
height: 48,
|
||||||
|
child: ConfirmDialogButton(
|
||||||
|
label: negativeLabel,
|
||||||
|
onTapAction: onNegativeAction,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget positiveButton = Container(
|
||||||
|
constraints: const BoxConstraints(minWidth: 153),
|
||||||
|
height: 48,
|
||||||
|
child: ConfirmDialogButton(
|
||||||
|
label: positiveLabel,
|
||||||
|
backgroundColor: AppColor.primaryMain,
|
||||||
|
textColor: Colors.white,
|
||||||
|
onTapAction: onPositiveAction,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget bodyWidget = Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Flexible(child: negativeButton),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Flexible(child: positiveButton),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
if (padding != null) {
|
||||||
|
return Padding(padding: padding!, child: bodyWidget);
|
||||||
|
} else {
|
||||||
|
return bodyWidget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,7 +32,7 @@ import 'package:tmail_ui_user/features/mailbox/presentation/styles/mailbox_icon_
|
|||||||
import 'package:tmail_ui_user/features/mailbox/presentation/styles/mailbox_item_widget_styles.dart';
|
import 'package:tmail_ui_user/features/mailbox/presentation/styles/mailbox_item_widget_styles.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_category_widget.dart';
|
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_category_widget.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_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/create_mailbox_name_input_decoration_builder.dart';
|
import 'package:tmail_ui_user/features/destination_picker/presentation/widgets/create_mailbox_name_input_decoration_builder.dart';
|
||||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/search_app_bar_widget.dart';
|
import 'package:tmail_ui_user/features/thread/presentation/widgets/search_app_bar_widget.dart';
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
import 'package:tmail_ui_user/main/utils/app_utils.dart';
|
import 'package:tmail_ui_user/main/utils/app_utils.dart';
|
||||||
@@ -413,7 +413,6 @@ class DestinationPickerView extends GetWidget<DestinationPickerController>
|
|||||||
?.map((mailboxNode) {
|
?.map((mailboxNode) {
|
||||||
if (mailboxNode.hasChildren()) {
|
if (mailboxNode.hasChildren()) {
|
||||||
return TreeViewChild(
|
return TreeViewChild(
|
||||||
context,
|
|
||||||
key: const Key('children_tree_mailbox_child'),
|
key: const Key('children_tree_mailbox_child'),
|
||||||
isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND,
|
isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND,
|
||||||
paddingChild: const EdgeInsetsDirectional.only(start: 14),
|
paddingChild: const EdgeInsetsDirectional.only(start: 14),
|
||||||
@@ -422,7 +421,9 @@ class DestinationPickerView extends GetWidget<DestinationPickerController>
|
|||||||
mailboxActions: actions,
|
mailboxActions: actions,
|
||||||
mailboxIdAlreadySelected: mailboxIdSelected,
|
mailboxIdAlreadySelected: mailboxIdSelected,
|
||||||
mailboxDisplayed: MailboxDisplayed.destinationPicker,
|
mailboxDisplayed: MailboxDisplayed.destinationPicker,
|
||||||
onOpenMailboxFolderClick: (node) => _pickMailboxNode(context, node),
|
onOpenMailboxFolderClick: (node) => node != null
|
||||||
|
? _pickMailboxNode(context, node)
|
||||||
|
: null,
|
||||||
onExpandFolderActionClick: (mailboxNode, itemKey) =>
|
onExpandFolderActionClick: (mailboxNode, itemKey) =>
|
||||||
controller.toggleMailboxFolder(
|
controller.toggleMailboxFolder(
|
||||||
mailboxNode,
|
mailboxNode,
|
||||||
@@ -443,7 +444,9 @@ class DestinationPickerView extends GetWidget<DestinationPickerController>
|
|||||||
mailboxDisplayed: MailboxDisplayed.destinationPicker,
|
mailboxDisplayed: MailboxDisplayed.destinationPicker,
|
||||||
mailboxIdAlreadySelected: mailboxIdSelected,
|
mailboxIdAlreadySelected: mailboxIdSelected,
|
||||||
mailboxActions: actions,
|
mailboxActions: actions,
|
||||||
onOpenMailboxFolderClick: (node) => _pickMailboxNode(context, node),
|
onOpenMailboxFolderClick: (node) => node != null
|
||||||
|
? _pickMailboxNode(context, node)
|
||||||
|
: null,
|
||||||
);
|
);
|
||||||
}})
|
}})
|
||||||
.toList() ?? <Widget>[];
|
.toList() ?? <Widget>[];
|
||||||
|
|||||||
@@ -199,7 +199,9 @@ abstract class BaseMailboxView extends GetWidget<MailboxController>
|
|||||||
.selectedMailbox
|
.selectedMailbox
|
||||||
.value,
|
.value,
|
||||||
onOpenMailboxFolderClick: (mailboxNode) =>
|
onOpenMailboxFolderClick: (mailboxNode) =>
|
||||||
controller.openMailbox(context, mailboxNode.item),
|
mailboxNode != null
|
||||||
|
? controller.openMailbox(context, mailboxNode.item)
|
||||||
|
: null,
|
||||||
onExpandFolderActionClick: mailboxNode.hasChildren()
|
onExpandFolderActionClick: mailboxNode.hasChildren()
|
||||||
? (mailboxNode, itemKey) => controller.toggleMailboxFolder(
|
? (mailboxNode, itemKey) => controller.toggleMailboxFolder(
|
||||||
mailboxNode,
|
mailboxNode,
|
||||||
@@ -228,7 +230,6 @@ abstract class BaseMailboxView extends GetWidget<MailboxController>
|
|||||||
|
|
||||||
if (mailboxNode.hasChildren()) {
|
if (mailboxNode.hasChildren()) {
|
||||||
return TreeViewChild(
|
return TreeViewChild(
|
||||||
context,
|
|
||||||
key: const Key('children_tree_mailbox_child'),
|
key: const Key('children_tree_mailbox_child'),
|
||||||
isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND,
|
isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND,
|
||||||
paddingChild: const EdgeInsetsDirectional.only(start: 12),
|
paddingChild: const EdgeInsetsDirectional.only(start: 12),
|
||||||
|
|||||||
@@ -843,15 +843,12 @@ class MailboxController extends BaseMailboxController
|
|||||||
}
|
}
|
||||||
|
|
||||||
void goToCreateNewMailboxView(BuildContext context, {PresentationMailbox? parentMailbox}) async {
|
void goToCreateNewMailboxView(BuildContext context, {PresentationMailbox? parentMailbox}) async {
|
||||||
if (session !=null && accountId != null) {
|
if (session != null && accountId != null) {
|
||||||
final arguments = MailboxCreatorArguments(
|
final arguments = MailboxCreatorArguments(
|
||||||
accountId!,
|
defaultMailboxTree.value,
|
||||||
defaultMailboxTree.value,
|
personalMailboxTree.value,
|
||||||
personalMailboxTree.value,
|
parentMailbox,
|
||||||
teamMailboxesTree.value,
|
);
|
||||||
mailboxDashBoardController.sessionCurrent!,
|
|
||||||
parentMailbox
|
|
||||||
);
|
|
||||||
|
|
||||||
final result = PlatformInfo.isWeb
|
final result = PlatformInfo.isWeb
|
||||||
? await DialogRouter.pushGeneralDialog(routeName: AppRoutes.mailboxCreator, arguments: arguments)
|
? await DialogRouter.pushGeneralDialog(routeName: AppRoutes.mailboxCreator, arguments: arguments)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
enum MailboxDisplayed {
|
enum MailboxDisplayed {
|
||||||
mailbox,
|
mailbox,
|
||||||
destinationPicker
|
destinationPicker,
|
||||||
|
modalFolder;
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,7 @@ typedef OnDragEmailToMailboxAccepted = void Function(List<PresentationEmail>, Pr
|
|||||||
typedef OnLongPressMailboxAction = void Function(PresentationMailbox);
|
typedef OnLongPressMailboxAction = void Function(PresentationMailbox);
|
||||||
|
|
||||||
typedef OnClickExpandMailboxNodeAction = void Function(MailboxNode, GlobalKey itemKey);
|
typedef OnClickExpandMailboxNodeAction = void Function(MailboxNode, GlobalKey itemKey);
|
||||||
typedef OnClickOpenMailboxNodeAction = void Function(MailboxNode);
|
typedef OnClickOpenMailboxNodeAction = void Function(MailboxNode?);
|
||||||
typedef OnSelectMailboxNodeAction = void Function(MailboxNode);
|
typedef OnSelectMailboxNodeAction = void Function(MailboxNode);
|
||||||
typedef OnClickOpenMenuMailboxNodeAction = Future<void> Function(RelativeRect, MailboxNode);
|
typedef OnClickOpenMenuMailboxNodeAction = Future<void> Function(RelativeRect, MailboxNode);
|
||||||
typedef OnLongPressMailboxNodeAction = void Function(MailboxNode);
|
typedef OnLongPressMailboxNodeAction = void Function(MailboxNode);
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:core/presentation/resources/image_paths.dart';
|
||||||
|
import 'package:core/presentation/utils/theme_utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox/presentation/styles/mailbox_icon_widget_styles.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox/presentation/styles/mailbox_item_widget_styles.dart';
|
||||||
|
|
||||||
|
class FolderItemWidget extends StatelessWidget {
|
||||||
|
final ImagePaths imagePaths;
|
||||||
|
final String folderName;
|
||||||
|
final bool isSelected;
|
||||||
|
final VoidCallback? onTapAction;
|
||||||
|
|
||||||
|
const FolderItemWidget({
|
||||||
|
super.key,
|
||||||
|
required this.imagePaths,
|
||||||
|
required this.folderName,
|
||||||
|
this.isSelected = false,
|
||||||
|
this.onTapAction,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
Widget itemWidget = Container(
|
||||||
|
padding: const EdgeInsetsDirectional.symmetric(
|
||||||
|
horizontal: MailboxItemWidgetStyles.itemPadding,
|
||||||
|
),
|
||||||
|
height: MailboxItemWidgetStyles.height,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset(
|
||||||
|
imagePaths.icFolderMailbox,
|
||||||
|
width: MailboxIconWidgetStyles.iconSize,
|
||||||
|
height: MailboxIconWidgetStyles.iconSize,
|
||||||
|
colorFilter: AppColor.primaryLinShare.asFilter(),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
const SizedBox(width: MailboxItemWidgetStyles.labelIconSpace),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
folderName,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: isSelected
|
||||||
|
? ThemeUtils.textStyleInter700(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 14,
|
||||||
|
)
|
||||||
|
: ThemeUtils.textStyleBodyBody3(
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: MailboxItemWidgetStyles.labelIconSpace),
|
||||||
|
if (isSelected)
|
||||||
|
SvgPicture.asset(
|
||||||
|
imagePaths.icCheck,
|
||||||
|
width: MailboxIconWidgetStyles.iconSize,
|
||||||
|
height: MailboxIconWidgetStyles.iconSize,
|
||||||
|
colorFilter: AppColor.primaryLinShare.asFilter(),
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (onTapAction != null) {
|
||||||
|
return Material(
|
||||||
|
type: MaterialType.transparency,
|
||||||
|
child: InkWell(
|
||||||
|
borderRadius: const BorderRadius.all(
|
||||||
|
Radius.circular(MailboxItemWidgetStyles.borderRadius),
|
||||||
|
),
|
||||||
|
hoverColor: AppColor.blue100,
|
||||||
|
onTap: onTapAction,
|
||||||
|
child: itemWidget,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return itemWidget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@ class LabelMailboxItemWidget extends StatefulWidget {
|
|||||||
final bool showTrailing;
|
final bool showTrailing;
|
||||||
final bool isItemHovered;
|
final bool isItemHovered;
|
||||||
final bool isSelected;
|
final bool isSelected;
|
||||||
|
final bool isSelectedFolderInModal;
|
||||||
final OnClickOpenMenuMailboxNodeAction? onMenuActionClick;
|
final OnClickOpenMenuMailboxNodeAction? onMenuActionClick;
|
||||||
final OnEmptyMailboxActionCallback? onEmptyMailboxActionCallback;
|
final OnEmptyMailboxActionCallback? onEmptyMailboxActionCallback;
|
||||||
final OnClickExpandMailboxNodeAction? onClickExpandMailboxNodeAction;
|
final OnClickExpandMailboxNodeAction? onClickExpandMailboxNodeAction;
|
||||||
@@ -35,6 +36,7 @@ class LabelMailboxItemWidget extends StatefulWidget {
|
|||||||
this.showTrailing = true,
|
this.showTrailing = true,
|
||||||
this.isItemHovered = false,
|
this.isItemHovered = false,
|
||||||
this.isSelected = false,
|
this.isSelected = false,
|
||||||
|
this.isSelectedFolderInModal = false,
|
||||||
this.onMenuActionClick,
|
this.onMenuActionClick,
|
||||||
this.onEmptyMailboxActionCallback,
|
this.onEmptyMailboxActionCallback,
|
||||||
this.onClickExpandMailboxNodeAction,
|
this.onClickExpandMailboxNodeAction,
|
||||||
@@ -219,6 +221,11 @@ class _LabelMailboxItemWidgetState extends State<LabelMailboxItemWidget> {
|
|||||||
color: _responsiveUtils.isDesktop(context) ? null : AppColor.iconFolder,
|
color: _responsiveUtils.isDesktop(context) ? null : AppColor.iconFolder,
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
);
|
);
|
||||||
|
} else if (widget.isSelectedFolderInModal) {
|
||||||
|
return ThemeUtils.textStyleInter700(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 14,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return _responsiveUtils.isWebDesktop(context)
|
return _responsiveUtils.isWebDesktop(context)
|
||||||
? ThemeUtils.textStyleBodyBody3(color: Colors.black)
|
? ThemeUtils.textStyleBodyBody3(color: Colors.black)
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class MailboxItemWidget extends StatefulWidget {
|
|||||||
final PresentationMailbox? mailboxNodeSelected;
|
final PresentationMailbox? mailboxNodeSelected;
|
||||||
final MailboxActions? mailboxActions;
|
final MailboxActions? mailboxActions;
|
||||||
final MailboxId? mailboxIdAlreadySelected;
|
final MailboxId? mailboxIdAlreadySelected;
|
||||||
|
final Color? hoverColor;
|
||||||
|
|
||||||
final OnClickExpandMailboxNodeAction? onExpandFolderActionClick;
|
final OnClickExpandMailboxNodeAction? onExpandFolderActionClick;
|
||||||
final OnClickOpenMailboxNodeAction? onOpenMailboxFolderClick;
|
final OnClickOpenMailboxNodeAction? onOpenMailboxFolderClick;
|
||||||
@@ -41,6 +42,7 @@ class MailboxItemWidget extends StatefulWidget {
|
|||||||
this.mailboxNodeSelected,
|
this.mailboxNodeSelected,
|
||||||
this.mailboxActions,
|
this.mailboxActions,
|
||||||
this.mailboxIdAlreadySelected,
|
this.mailboxIdAlreadySelected,
|
||||||
|
this.hoverColor,
|
||||||
this.onExpandFolderActionClick,
|
this.onExpandFolderActionClick,
|
||||||
this.onOpenMailboxFolderClick,
|
this.onOpenMailboxFolderClick,
|
||||||
this.onSelectMailboxFolderClick,
|
this.onSelectMailboxFolderClick,
|
||||||
@@ -229,11 +231,11 @@ class _MailboxItemWidgetState extends State<MailboxItemWidget> {
|
|||||||
child: Material(
|
child: Material(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () => !_isSelectActionNoValid
|
onTap: !isSelectedFolderInModal
|
||||||
? widget.onOpenMailboxFolderClick?.call(widget.mailboxNode)
|
? () => widget.onOpenMailboxFolderClick?.call(widget.mailboxNode)
|
||||||
: null,
|
: null,
|
||||||
customBorder: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8))),
|
customBorder: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8))),
|
||||||
hoverColor: AppColor.colorMailboxHovered,
|
hoverColor: widget.hoverColor ?? AppColor.colorMailboxHovered,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsetsDirectional.symmetric(
|
padding: const EdgeInsetsDirectional.symmetric(
|
||||||
horizontal: MailboxItemWidgetStyles.itemPadding,
|
horizontal: MailboxItemWidgetStyles.itemPadding,
|
||||||
@@ -255,14 +257,17 @@ class _MailboxItemWidgetState extends State<MailboxItemWidget> {
|
|||||||
showTrailing: false,
|
showTrailing: false,
|
||||||
isSelected: _isSelected,
|
isSelected: _isSelected,
|
||||||
isItemHovered: _isItemHovered,
|
isItemHovered: _isItemHovered,
|
||||||
|
isSelectedFolderInModal: isSelectedFolderInModal,
|
||||||
onMenuActionClick: widget.onMenuActionClick,
|
onMenuActionClick: widget.onMenuActionClick,
|
||||||
onEmptyMailboxActionCallback: widget.onEmptyMailboxActionCallback,
|
onEmptyMailboxActionCallback: widget.onEmptyMailboxActionCallback,
|
||||||
onClickExpandMailboxNodeAction: widget.onExpandFolderActionClick,
|
onClickExpandMailboxNodeAction: widget.onExpandFolderActionClick,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
if (_isSelectActionNoValid)
|
if (isSelectedFolderInModal)
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
_imagePaths.icSelectedSB,
|
isFolderModalActive
|
||||||
|
? _imagePaths.icCheck
|
||||||
|
: _imagePaths.icSelectedSB,
|
||||||
width: MailboxItemWidgetStyles.selectionIconSize,
|
width: MailboxItemWidgetStyles.selectionIconSize,
|
||||||
height: MailboxItemWidgetStyles.selectionIconSize,
|
height: MailboxItemWidgetStyles.selectionIconSize,
|
||||||
fit: BoxFit.fill
|
fit: BoxFit.fill
|
||||||
@@ -282,24 +287,25 @@ class _MailboxItemWidgetState extends State<MailboxItemWidget> {
|
|||||||
widget.mailboxNodeSelected?.id == widget.mailboxNode.item.id;
|
widget.mailboxNodeSelected?.id == widget.mailboxNode.item.id;
|
||||||
|
|
||||||
Color get backgroundColorItem {
|
Color get backgroundColorItem {
|
||||||
if (widget.mailboxDisplayed == MailboxDisplayed.destinationPicker) {
|
if (widget.mailboxDisplayed == MailboxDisplayed.mailbox) {
|
||||||
return Colors.white;
|
return _isSelected ? AppColor.blue100 : Colors.transparent;
|
||||||
} else {
|
|
||||||
if (_isSelected) {
|
|
||||||
return AppColor.blue100;
|
|
||||||
} else {
|
|
||||||
return Colors.transparent;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return Colors.white;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get _isSelectActionNoValid => widget.mailboxNode.item.id == widget.mailboxIdAlreadySelected &&
|
bool get isFolderModalActive =>
|
||||||
widget.mailboxDisplayed == MailboxDisplayed.destinationPicker &&
|
widget.mailboxDisplayed == MailboxDisplayed.modalFolder;
|
||||||
(
|
|
||||||
widget.mailboxActions == MailboxActions.select ||
|
bool get isSelectedFolderInModal {
|
||||||
widget.mailboxActions == MailboxActions.create ||
|
final isDestinationPickerActive =
|
||||||
widget.mailboxActions == MailboxActions.moveEmail
|
widget.mailboxDisplayed == MailboxDisplayed.destinationPicker &&
|
||||||
);
|
(widget.mailboxActions == MailboxActions.select ||
|
||||||
|
widget.mailboxActions == MailboxActions.create ||
|
||||||
|
widget.mailboxActions == MailboxActions.moveEmail);
|
||||||
|
|
||||||
|
return widget.mailboxNode.item.id == widget.mailboxIdAlreadySelected &&
|
||||||
|
(isDestinationPickerActive || isFolderModalActive);
|
||||||
|
}
|
||||||
|
|
||||||
bool get _isIconDisplayed =>
|
bool get _isIconDisplayed =>
|
||||||
widget.mailboxNode.item.isPersonal ||
|
widget.mailboxNode.item.isPersonal ||
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
|
|
||||||
import 'package:core/core.dart';
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
|
||||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
|
||||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||||
import 'package:model/model.dart';
|
import 'package:model/model.dart';
|
||||||
import 'package:tmail_ui_user/features/base/base_controller.dart';
|
import 'package:tmail_ui_user/features/base/base_controller.dart';
|
||||||
import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart';
|
import 'package:tmail_ui_user/features/base/mixin/expand_folder_trigger_scrollable_mixin.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.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_node.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree.dart';
|
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_creator/domain/model/verification/duplicate_name_validator.dart';
|
import 'package:tmail_ui_user/features/mailbox_creator/domain/model/verification/duplicate_name_validator.dart';
|
||||||
@@ -20,27 +16,24 @@ import 'package:tmail_ui_user/features/mailbox_creator/domain/usecases/verify_na
|
|||||||
import 'package:tmail_ui_user/features/mailbox_creator/presentation/extensions/validator_failure_extension.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/mailbox_creator_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/model/new_mailbox_arguments.dart';
|
||||||
import 'package:tmail_ui_user/main/routes/app_routes.dart';
|
|
||||||
import 'package:tmail_ui_user/main/routes/dialog_router.dart';
|
|
||||||
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
||||||
|
|
||||||
class MailboxCreatorController extends BaseController {
|
class MailboxCreatorController extends BaseController
|
||||||
|
with ExpandFolderTriggerScrollableMixin {
|
||||||
|
|
||||||
final VerifyNameInteractor _verifyNameInteractor;
|
final VerifyNameInteractor _verifyNameInteractor;
|
||||||
|
|
||||||
final selectedMailbox = Rxn<PresentationMailbox>();
|
final selectedMailbox = Rxn<PresentationMailbox>();
|
||||||
final newNameMailbox = Rxn<String>();
|
final newNameMailbox = Rxn<String>();
|
||||||
|
final isFolderModalEnabled = RxBool(false);
|
||||||
bool _createdMailbox = false;
|
bool _createdMailbox = false;
|
||||||
|
|
||||||
|
final personalMailboxTree = MailboxTree(MailboxNode.root()).obs;
|
||||||
|
final defaultMailboxTree = MailboxTree(MailboxNode.root()).obs;
|
||||||
|
|
||||||
final FocusNode nameInputFocusNode = FocusNode();
|
final FocusNode nameInputFocusNode = FocusNode();
|
||||||
final TextEditingController nameInputController = TextEditingController();
|
final TextEditingController nameInputController = TextEditingController();
|
||||||
|
final ScrollController listFolderScrollController = ScrollController();
|
||||||
MailboxCreatorArguments? arguments;
|
|
||||||
AccountId? accountId;
|
|
||||||
Session? _session;
|
|
||||||
MailboxTree? defaultMailboxTree;
|
|
||||||
MailboxTree? personalMailboxTree;
|
|
||||||
MailboxTree? teamMailboxesTre;
|
|
||||||
|
|
||||||
List<String> listMailboxNameAsStringExist = <String>[];
|
List<String> listMailboxNameAsStringExist = <String>[];
|
||||||
|
|
||||||
@@ -51,47 +44,35 @@ class MailboxCreatorController extends BaseController {
|
|||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
log('MailboxCreatorController::onInit():arguments: ${Get.arguments}');
|
MailboxCreatorArguments? arguments = Get.arguments;
|
||||||
arguments = Get.arguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onReady() {
|
|
||||||
super.onReady();
|
|
||||||
log('MailboxCreatorController::onReady():');
|
|
||||||
if (arguments != null) {
|
if (arguments != null) {
|
||||||
personalMailboxTree = arguments!.personalMailboxTree;
|
personalMailboxTree.value = arguments.personalMailboxTree;
|
||||||
defaultMailboxTree = arguments!.defaultMailboxTree;
|
defaultMailboxTree.value = arguments.defaultMailboxTree;
|
||||||
teamMailboxesTre = arguments!.teamMailboxesTree;
|
selectedMailbox.value = arguments.selectedMailbox;
|
||||||
accountId = arguments!.accountId;
|
|
||||||
_session = arguments!.session;
|
|
||||||
if (arguments!.selectedMailbox != null) {
|
|
||||||
selectedMailbox.value = arguments!.selectedMailbox;
|
|
||||||
}
|
|
||||||
_createListMailboxNameAsStringInMailboxLocation();
|
_createListMailboxNameAsStringInMailboxLocation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onClose() {
|
void onClose() {
|
||||||
log('MailboxCreatorController::onClose():');
|
listMailboxNameAsStringExist = [];
|
||||||
|
_createdMailbox = false;
|
||||||
nameInputFocusNode.dispose();
|
nameInputFocusNode.dispose();
|
||||||
nameInputController.dispose();
|
nameInputController.dispose();
|
||||||
|
listFolderScrollController.dispose();
|
||||||
super.onClose();
|
super.onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
MailboxNode? _findMailboxNodeById(MailboxId mailboxId) {
|
MailboxNode? _findMailboxNodeById(MailboxId mailboxId) {
|
||||||
final mailboxNode = defaultMailboxTree?.findNode((node) => node.item.id == mailboxId)
|
final mailboxNode = defaultMailboxTree.value.findNode((node) => node.item.id == mailboxId)
|
||||||
?? personalMailboxTree?.findNode((node) => node.item.id == mailboxId)
|
?? personalMailboxTree.value.findNode((node) => node.item.id == mailboxId);
|
||||||
?? teamMailboxesTre?.findNode((node) => node.item.id == mailboxId);
|
|
||||||
return mailboxNode;
|
return mailboxNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _createListMailboxNameAsStringInMailboxLocation() {
|
void _createListMailboxNameAsStringInMailboxLocation() {
|
||||||
if (selectedMailbox.value == null) {
|
if (selectedMailbox.value == null) {
|
||||||
final allChildrenAtMailboxLocation = (defaultMailboxTree?.root.childrenItems ?? <MailboxNode>[])
|
final allChildrenAtMailboxLocation = (defaultMailboxTree.value.root.childrenItems ?? <MailboxNode>[])
|
||||||
+ (personalMailboxTree?.root.childrenItems ?? <MailboxNode>[])
|
+ (personalMailboxTree.value.root.childrenItems ?? <MailboxNode>[]);
|
||||||
+ (teamMailboxesTre?.root.childrenItems ?? <MailboxNode>[]);
|
|
||||||
if (allChildrenAtMailboxLocation.isNotEmpty) {
|
if (allChildrenAtMailboxLocation.isNotEmpty) {
|
||||||
listMailboxNameAsStringExist = allChildrenAtMailboxLocation
|
listMailboxNameAsStringExist = allChildrenAtMailboxLocation
|
||||||
.where((mailboxNode) => mailboxNode.nameNotEmpty)
|
.where((mailboxNode) => mailboxNode.nameNotEmpty)
|
||||||
@@ -140,33 +121,22 @@ class MailboxCreatorController extends BaseController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectMailboxLocation(BuildContext context) async {
|
void openFolderModal(BuildContext context) {
|
||||||
KeyboardUtils.hideKeyboard(context);
|
nameInputFocusNode.unfocus();
|
||||||
|
|
||||||
if (accountId != null) {
|
if (!responsiveUtils.isMobile(context)) {
|
||||||
final arguments = DestinationPickerArguments(
|
isFolderModalEnabled.value = true;
|
||||||
accountId!,
|
|
||||||
MailboxActions.create,
|
|
||||||
_session,
|
|
||||||
mailboxIdSelected: selectedMailbox.value?.id);
|
|
||||||
|
|
||||||
final destinationMailbox = PlatformInfo.isWeb
|
|
||||||
? await DialogRouter.pushGeneralDialog(routeName: AppRoutes.destinationPicker, arguments: arguments)
|
|
||||||
: await push(AppRoutes.destinationPicker, arguments: arguments);
|
|
||||||
|
|
||||||
if (destinationMailbox is PresentationMailbox) {
|
|
||||||
final mailboxDestination = destinationMailbox == PresentationMailbox.unifiedMailbox
|
|
||||||
? null
|
|
||||||
: destinationMailbox;
|
|
||||||
|
|
||||||
selectedMailbox.value = mailboxDestination;
|
|
||||||
_createListMailboxNameAsStringInMailboxLocation();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void selectMailboxLocation(MailboxNode? mailboxDestination) {
|
||||||
|
isFolderModalEnabled.value = false;
|
||||||
|
selectedMailbox.value = mailboxDestination?.item;
|
||||||
|
_createListMailboxNameAsStringInMailboxLocation();
|
||||||
|
}
|
||||||
|
|
||||||
void createNewMailbox(BuildContext context) {
|
void createNewMailbox(BuildContext context) {
|
||||||
KeyboardUtils.hideKeyboard(context);
|
nameInputFocusNode.unfocus();
|
||||||
|
|
||||||
final nameMailbox = newNameMailbox.value;
|
final nameMailbox = newNameMailbox.value;
|
||||||
final nameValidated = getErrorInputNameString(context);
|
final nameValidated = getErrorInputNameString(context);
|
||||||
@@ -180,11 +150,35 @@ class MailboxCreatorController extends BaseController {
|
|||||||
MailboxName(nameMailbox),
|
MailboxName(nameMailbox),
|
||||||
mailboxLocation: selectedMailbox.value);
|
mailboxLocation: selectedMailbox.value);
|
||||||
popBack(result: newMailboxArguments);
|
popBack(result: newMailboxArguments);
|
||||||
|
} else {
|
||||||
|
newNameMailbox.refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void closeMailboxCreator(BuildContext context) {
|
void toggleFolder(MailboxNode selectedMailboxNode, GlobalKey itemKey) {
|
||||||
KeyboardUtils.hideKeyboard(context);
|
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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void closeView() {
|
||||||
|
nameInputFocusNode.unfocus();
|
||||||
popBack();
|
popBack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,24 +1,20 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:core/presentation/extensions/color_extension.dart';
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
import 'package:core/presentation/utils/style_utils.dart';
|
|
||||||
import 'package:core/presentation/utils/theme_utils.dart';
|
import 'package:core/presentation/utils/theme_utils.dart';
|
||||||
import 'package:core/presentation/views/text/text_field_builder.dart';
|
|
||||||
import 'package:core/utils/app_logger.dart';
|
|
||||||
import 'package:core/utils/direction_utils.dart';
|
|
||||||
import 'package:core/utils/platform_info.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
import 'package:tmail_ui_user/features/base/widget/default_field/default_button_arrow_down_field_widget.dart';
|
||||||
|
import 'package:tmail_ui_user/features/base/widget/default_field/default_close_button_widget.dart';
|
||||||
|
import 'package:tmail_ui_user/features/base/widget/label_input_field_builder.dart';
|
||||||
|
import 'package:tmail_ui_user/features/base/widget/modal_list_action_button_widget.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentation_mailbox_extension.dart';
|
import 'package:tmail_ui_user/features/mailbox/presentation/extensions/presentation_mailbox_extension.dart';
|
||||||
|
import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_icon_widget.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_creator/presentation/mailbox_creator_controller.dart';
|
import 'package:tmail_ui_user/features/mailbox_creator/presentation/mailbox_creator_controller.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_creator/presentation/widgets/app_bar_mailbox_creator_builder.dart';
|
import 'package:tmail_ui_user/features/mailbox_creator/presentation/widgets/modal_folder_tree_list_widget.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox_creator/presentation/widgets/create_mailbox_name_input_decoration_builder.dart';
|
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||||
|
|
||||||
class MailboxCreatorView extends GetWidget<MailboxCreatorController> {
|
class MailboxCreatorView extends GetWidget<MailboxCreatorController> {
|
||||||
|
|
||||||
final _maxHeight = 656.0;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final controller = Get.find<MailboxCreatorController>();
|
final controller = Get.find<MailboxCreatorController>();
|
||||||
|
|
||||||
@@ -26,234 +22,181 @@ class MailboxCreatorView extends GetWidget<MailboxCreatorController> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
log('MailboxCreatorView::build():');
|
final appLocalizations = AppLocalizations.of(context);
|
||||||
return PointerInterceptor(
|
final theme = Theme.of(context);
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () => controller.closeMailboxCreator(context),
|
Widget bodyWidget = Container(
|
||||||
child: Card(
|
decoration: BoxDecoration(
|
||||||
margin: EdgeInsets.zero,
|
color: Colors.white,
|
||||||
borderOnForeground: false,
|
borderRadius: const BorderRadius.all(Radius.circular(16)),
|
||||||
color: Colors.transparent,
|
boxShadow: [
|
||||||
child: SafeArea(
|
BoxShadow(
|
||||||
top: PlatformInfo.isMobile && controller.responsiveUtils.isPortraitMobile(context),
|
color: Colors.black.withValues(alpha: 0.08),
|
||||||
bottom: false,
|
blurRadius: 24,
|
||||||
left: false,
|
offset: const Offset(0, 2),
|
||||||
right: false,
|
|
||||||
child: Center(
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: () => FocusScope.of(context).unfocus(),
|
|
||||||
child: Container(
|
|
||||||
margin: _getMarginView(context),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.white,
|
|
||||||
borderRadius: _getRadiusView(context),
|
|
||||||
boxShadow: const [
|
|
||||||
BoxShadow(
|
|
||||||
color: AppColor.colorShadowLayerBottom,
|
|
||||||
blurRadius: 96,
|
|
||||||
spreadRadius: 96,
|
|
||||||
offset: Offset.zero),
|
|
||||||
BoxShadow(
|
|
||||||
color: AppColor.colorShadowLayerTop,
|
|
||||||
blurRadius: 2,
|
|
||||||
spreadRadius: 2,
|
|
||||||
offset: Offset.zero),
|
|
||||||
]),
|
|
||||||
width: _getWidthView(context),
|
|
||||||
height: _getHeightView(context),
|
|
||||||
child: ClipRRect(
|
|
||||||
borderRadius: _getRadiusView(context),
|
|
||||||
child: SafeArea(
|
|
||||||
top: false,
|
|
||||||
bottom: false,
|
|
||||||
left: PlatformInfo.isMobile && controller.responsiveUtils.isLandscapeMobile(context),
|
|
||||||
right: PlatformInfo.isMobile && controller.responsiveUtils.isLandscapeMobile(context),
|
|
||||||
child: Column(children: [
|
|
||||||
_buildAppBar(context),
|
|
||||||
const Divider(color: AppColor.colorDividerDestinationPicker, height: 1),
|
|
||||||
_buildCreateMailboxNameInput(context),
|
|
||||||
_buildMailboxLocation(context),
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black.withValues(alpha: 0.08),
|
||||||
|
blurRadius: 2,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
width: min(
|
||||||
|
controller.responsiveUtils.getSizeScreenWidth(context) - 32,
|
||||||
|
554,
|
||||||
|
),
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
maxHeight: min(
|
||||||
|
controller.responsiveUtils.getSizeScreenHeight(context) - 100,
|
||||||
|
671,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
clipBehavior: Clip.antiAlias,
|
||||||
}
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsetsDirectional.only(
|
||||||
|
start: 32,
|
||||||
|
end: 32,
|
||||||
|
bottom: controller.responsiveUtils.isMobile(context) ? 0 : 16,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: 64,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(
|
||||||
|
appLocalizations.createANewFolder,
|
||||||
|
style: theme.textTheme.headlineSmall?.copyWith(
|
||||||
|
color: AppColor.m3SurfaceBackground,
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Obx(() {
|
||||||
|
final folderName =
|
||||||
|
controller.selectedMailbox.value?.getDisplayName(context) ??
|
||||||
|
appLocalizations.personalFolders;
|
||||||
|
return Center(
|
||||||
|
child: Text(
|
||||||
|
appLocalizations
|
||||||
|
.subtitleDisplayTheFolderNameLocationInFolderCreationModal(
|
||||||
|
folderName,
|
||||||
|
),
|
||||||
|
style: ThemeUtils.textStyleInter400.copyWith(
|
||||||
|
color: AppColor.steelGrayA540,
|
||||||
|
fontSize: 13,
|
||||||
|
height: 20 / 13,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
const SizedBox(height: 32),
|
||||||
|
Obx(
|
||||||
|
() => LabelInputFieldBuilder(
|
||||||
|
label: AppLocalizations.of(context).folderName,
|
||||||
|
hintText: AppLocalizations.of(context).enterTheFolderName,
|
||||||
|
textEditingController: controller.nameInputController,
|
||||||
|
focusNode: controller.nameInputFocusNode,
|
||||||
|
errorText: controller.getErrorInputNameString(context),
|
||||||
|
arrangeHorizontally: false,
|
||||||
|
isLabelHasColon: false,
|
||||||
|
labelStyle: ThemeUtils.textStyleInter600().copyWith(
|
||||||
|
fontSize: 14,
|
||||||
|
height: 18 / 14,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
runSpacing: 16,
|
||||||
|
inputFieldMaxWidth: double.infinity,
|
||||||
|
onTextChange: controller.setNewNameMailbox,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 26, bottom: 16),
|
||||||
|
child: Text(
|
||||||
|
appLocalizations.selectTheFolderLocation,
|
||||||
|
style: ThemeUtils.textStyleInter600().copyWith(
|
||||||
|
fontSize: 14,
|
||||||
|
height: 18 / 14,
|
||||||
|
color: Colors.black,
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Obx(() {
|
||||||
|
final selectedMailbox = controller.selectedMailbox.value;
|
||||||
|
final isFolderModalEnabled =
|
||||||
|
controller.isFolderModalEnabled.isTrue;
|
||||||
|
|
||||||
Widget _buildAppBar(BuildContext context) {
|
return Flexible(
|
||||||
return (AppBarMailboxCreatorBuilder(
|
child: AnimatedSize(
|
||||||
context,
|
duration: const Duration(milliseconds: 300),
|
||||||
title: AppLocalizations.of(context).newFolder,
|
curve: Curves.easeInOut,
|
||||||
isValidated: true)
|
alignment: Alignment.topCenter,
|
||||||
..addOnCancelActionClick(() => controller.closeMailboxCreator(context))
|
child: isFolderModalEnabled
|
||||||
..addOnDoneActionClick(() => controller.createNewMailbox(context)))
|
? Container(
|
||||||
.build();
|
decoration: BoxDecoration(
|
||||||
}
|
borderRadius: const BorderRadius.all(
|
||||||
|
Radius.circular(10),
|
||||||
Widget _buildCreateMailboxNameInput(BuildContext context) {
|
),
|
||||||
return Padding(
|
border: Border.all(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
color: AppColor.m3Neutral90,
|
||||||
child: Obx(() => TextFieldBuilder(
|
width: 1,
|
||||||
onTextChange: controller.setNewNameMailbox,
|
),
|
||||||
keyboardType: TextInputType.visiblePassword,
|
),
|
||||||
cursorColor: AppColor.colorTextButton,
|
padding: const EdgeInsetsDirectional.only(
|
||||||
controller: controller.nameInputController,
|
start: 14,
|
||||||
textDirection: DirectionUtils.getDirectionByLanguage(context),
|
top: 13,
|
||||||
maxLines: 1,
|
bottom: 13,
|
||||||
textStyle: ThemeUtils.defaultTextStyleInterFont.copyWith(
|
end: 4,
|
||||||
color: AppColor.colorNameEmail,
|
),
|
||||||
fontSize: 16,
|
child: Obx(() => ModalFolderTreeListWidget(
|
||||||
overflow: CommonTextStyle.defaultTextOverFlow),
|
defaultTree: controller.defaultMailboxTree.value,
|
||||||
focusNode: controller.nameInputFocusNode,
|
personalTree: controller.personalMailboxTree.value,
|
||||||
decoration: (CreateMailboxNameInputDecorationBuilder()
|
imagePaths: controller.imagePaths,
|
||||||
..setHintText(AppLocalizations.of(context).hintInputCreateNewFolder)
|
listScrollController:
|
||||||
..setErrorText(controller.getErrorInputNameString(context)))
|
controller.listFolderScrollController,
|
||||||
.build(),
|
mailboxIdSelected: selectedMailbox?.id,
|
||||||
))
|
onSelectFolderAction: controller.selectMailboxLocation,
|
||||||
);
|
onToggleFolderAction: controller.toggleFolder,
|
||||||
}
|
)),
|
||||||
|
)
|
||||||
Widget _buildMailboxLocation(BuildContext context) {
|
: DefaultButtonArrowDownFieldWidget(
|
||||||
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
text: selectedMailbox?.getDisplayName(context) ??
|
||||||
Padding(
|
appLocalizations.personalFolders,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
icon: MailboxIconWidget(
|
||||||
child: Text(
|
icon: selectedMailbox?.getMailboxIcon(controller.imagePaths)
|
||||||
AppLocalizations.of(context).selectParentFolder,
|
?? controller.imagePaths.icFolderMailbox,
|
||||||
textAlign: TextAlign.left,
|
),
|
||||||
style: ThemeUtils.defaultTextStyleInterFont.copyWith(
|
iconArrowDown: controller.imagePaths.icDropDown,
|
||||||
fontSize: 13,
|
onTap: () => controller.openFolderModal(context),
|
||||||
color: AppColor.colorHintSearchBar,
|
),
|
||||||
fontWeight: FontWeight.normal)),
|
),
|
||||||
),
|
);
|
||||||
Container(
|
}),
|
||||||
alignment: Alignment.center,
|
ModalListActionButtonWidget(
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 16),
|
positiveLabel: appLocalizations.createFolder,
|
||||||
decoration: BoxDecoration(
|
negativeLabel: appLocalizations.cancel,
|
||||||
borderRadius: BorderRadius.circular(14),
|
padding: const EdgeInsets.symmetric(vertical: 25),
|
||||||
color: AppColor.colorBgMailbox
|
onPositiveAction: () => controller.createNewMailbox(context),
|
||||||
|
onNegativeAction: controller.closeView,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: Material(
|
DefaultCloseButtonWidget(
|
||||||
color: Colors.transparent,
|
iconClose: controller.imagePaths.icCloseDialog,
|
||||||
child: InkWell(
|
onTapActionCallback: controller.closeView,
|
||||||
onTap: () => controller.selectMailboxLocation(context),
|
),
|
||||||
customBorder: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)),
|
],
|
||||||
child: Row(children: [
|
),
|
||||||
const SizedBox(width: 12),
|
);
|
||||||
Obx(() => SvgPicture.asset(
|
|
||||||
controller.selectedMailbox.value?.getMailboxIcon(controller.imagePaths) ?? controller.imagePaths.icFolderMailbox,
|
|
||||||
width: PlatformInfo.isWeb ? 20 : 24,
|
|
||||||
height: PlatformInfo.isWeb ? 20 : 24,
|
|
||||||
fit: BoxFit.fill)),
|
|
||||||
const SizedBox(width: 12),
|
|
||||||
Expanded(child: Obx(() => Text(
|
|
||||||
controller.selectedMailbox.value?.getDisplayName(context) ?? AppLocalizations.of(context).allFolders,
|
|
||||||
maxLines: 1,
|
|
||||||
softWrap: CommonTextStyle.defaultSoftWrap,
|
|
||||||
overflow: CommonTextStyle.defaultTextOverFlow,
|
|
||||||
style: ThemeUtils.defaultTextStyleInterFont.copyWith(
|
|
||||||
fontSize: 15,
|
|
||||||
color: controller.selectedMailbox.value == null
|
|
||||||
? AppColor.colorHintSearchBar
|
|
||||||
: AppColor.colorNameEmail),
|
|
||||||
))),
|
|
||||||
const SizedBox(width: 12),
|
|
||||||
IconButton(
|
|
||||||
color: AppColor.primaryColor,
|
|
||||||
icon: SvgPicture.asset(
|
|
||||||
DirectionUtils.isDirectionRTLByLanguage(context)
|
|
||||||
? controller.imagePaths.icBack
|
|
||||||
: controller.imagePaths.icCollapseFolder,
|
|
||||||
colorFilter: AppColor.colorCollapseMailbox.asFilter(),
|
|
||||||
fit: BoxFit.fill),
|
|
||||||
onPressed: () => controller.selectMailboxLocation(context))
|
|
||||||
])),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
double _getWidthView(BuildContext context) {
|
return Center(child: bodyWidget);
|
||||||
if (PlatformInfo.isWeb) {
|
|
||||||
if (controller.responsiveUtils.isMobile(context)) {
|
|
||||||
return double.infinity;
|
|
||||||
} else {
|
|
||||||
return 556;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (controller.responsiveUtils.isLandscapeMobile(context) ||
|
|
||||||
controller.responsiveUtils.isPortraitMobile(context)) {
|
|
||||||
return double.infinity;
|
|
||||||
} else {
|
|
||||||
return 556;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
double _getHeightView(BuildContext context) {
|
|
||||||
if (PlatformInfo.isWeb) {
|
|
||||||
if (controller.responsiveUtils.isMobile(context)) {
|
|
||||||
return double.infinity;
|
|
||||||
} else {
|
|
||||||
if (controller.responsiveUtils.getSizeScreenHeight(context) > _maxHeight) {
|
|
||||||
return _maxHeight;
|
|
||||||
} else {
|
|
||||||
return double.infinity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (controller.responsiveUtils.isLandscapeMobile(context) ||
|
|
||||||
controller.responsiveUtils.isPortraitMobile(context)) {
|
|
||||||
return double.infinity;
|
|
||||||
} else {
|
|
||||||
if (controller.responsiveUtils.getSizeScreenHeight(context) > _maxHeight) {
|
|
||||||
return _maxHeight;
|
|
||||||
} else {
|
|
||||||
return double.infinity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
EdgeInsets _getMarginView(BuildContext context) {
|
|
||||||
if (PlatformInfo.isWeb) {
|
|
||||||
if (controller.responsiveUtils.isMobile(context)) {
|
|
||||||
return EdgeInsets.zero;
|
|
||||||
} else {
|
|
||||||
if (controller.responsiveUtils.getSizeScreenHeight(context) > _maxHeight) {
|
|
||||||
return const EdgeInsets.symmetric(vertical: 12);
|
|
||||||
} else {
|
|
||||||
return const EdgeInsets.symmetric(vertical: 50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (controller.responsiveUtils.isLandscapeMobile(context) ||
|
|
||||||
controller.responsiveUtils.isPortraitMobile(context)) {
|
|
||||||
return EdgeInsets.zero;
|
|
||||||
} else {
|
|
||||||
if (controller.responsiveUtils.getSizeScreenHeight(context) > _maxHeight) {
|
|
||||||
return const EdgeInsets.symmetric(vertical: 12);
|
|
||||||
} else {
|
|
||||||
return const EdgeInsets.symmetric(vertical: 50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BorderRadius _getRadiusView(BuildContext context) {
|
|
||||||
if (PlatformInfo.isMobile && controller.responsiveUtils.isLandscapeMobile(context)) {
|
|
||||||
return BorderRadius.zero;
|
|
||||||
} else if (controller.responsiveUtils.isMobile(context)) {
|
|
||||||
return const BorderRadius.only(
|
|
||||||
topRight: Radius.circular(16),
|
|
||||||
topLeft: Radius.circular(16));
|
|
||||||
} else {
|
|
||||||
return const BorderRadius.all(Radius.circular(16));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,34 +1,23 @@
|
|||||||
|
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
|
||||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
|
||||||
import 'package:model/mailbox/presentation_mailbox.dart';
|
import 'package:model/mailbox/presentation_mailbox.dart';
|
||||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree.dart';
|
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree.dart';
|
||||||
|
|
||||||
class MailboxCreatorArguments with EquatableMixin{
|
class MailboxCreatorArguments with EquatableMixin{
|
||||||
final AccountId accountId;
|
|
||||||
final MailboxTree personalMailboxTree;
|
final MailboxTree personalMailboxTree;
|
||||||
final MailboxTree defaultMailboxTree;
|
final MailboxTree defaultMailboxTree;
|
||||||
final MailboxTree teamMailboxesTree;
|
|
||||||
final Session session;
|
|
||||||
final PresentationMailbox? selectedMailbox;
|
final PresentationMailbox? selectedMailbox;
|
||||||
|
|
||||||
MailboxCreatorArguments(
|
MailboxCreatorArguments(
|
||||||
this.accountId,
|
this.defaultMailboxTree,
|
||||||
this.defaultMailboxTree,
|
|
||||||
this.personalMailboxTree,
|
this.personalMailboxTree,
|
||||||
this.teamMailboxesTree,
|
this.selectedMailbox,
|
||||||
this.session,
|
|
||||||
this.selectedMailbox
|
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [
|
List<Object?> get props => [
|
||||||
accountId,
|
defaultMailboxTree,
|
||||||
defaultMailboxTree,
|
|
||||||
personalMailboxTree,
|
personalMailboxTree,
|
||||||
teamMailboxesTree,
|
selectedMailbox,
|
||||||
session,
|
|
||||||
selectedMailbox
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
-92
@@ -1,92 +0,0 @@
|
|||||||
|
|
||||||
import 'package:core/core.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
|
||||||
|
|
||||||
typedef OnCancelActionClick = void Function();
|
|
||||||
typedef OnDoneActionClick = void Function();
|
|
||||||
|
|
||||||
class AppBarMailboxCreatorBuilder {
|
|
||||||
OnCancelActionClick? _cancelActionClick;
|
|
||||||
OnDoneActionClick? _onDoneActionClick;
|
|
||||||
|
|
||||||
final BuildContext _context;
|
|
||||||
final bool isValidated;
|
|
||||||
final String? title;
|
|
||||||
|
|
||||||
AppBarMailboxCreatorBuilder(
|
|
||||||
this._context,
|
|
||||||
{
|
|
||||||
this.title,
|
|
||||||
this.isValidated = false
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
void addOnCancelActionClick(OnCancelActionClick onCancelActionClick) {
|
|
||||||
_cancelActionClick = onCancelActionClick;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addOnDoneActionClick(OnDoneActionClick onDoneActionClick) {
|
|
||||||
_onDoneActionClick = onDoneActionClick;
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget build() {
|
|
||||||
return Container(
|
|
||||||
color: Colors.white,
|
|
||||||
height: 52,
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
|
||||||
child: Row(children: [
|
|
||||||
_buildCancelButton(),
|
|
||||||
Expanded(child: _buildTitle()),
|
|
||||||
_buildCreateButton()
|
|
||||||
])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildCancelButton() {
|
|
||||||
return Material(
|
|
||||||
borderRadius: BorderRadius.circular(20),
|
|
||||||
color: Colors.transparent,
|
|
||||||
child: TextButton(
|
|
||||||
child: Text(
|
|
||||||
AppLocalizations.of(_context).cancel,
|
|
||||||
style: ThemeUtils.defaultTextStyleInterFont.copyWith(fontSize: 17, color: AppColor.colorTextButton),
|
|
||||||
),
|
|
||||||
onPressed: () => _cancelActionClick?.call()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildCreateButton() {
|
|
||||||
return Material(
|
|
||||||
borderRadius: BorderRadius.circular(20),
|
|
||||||
color: Colors.transparent,
|
|
||||||
child: TextButton(
|
|
||||||
child: Text(
|
|
||||||
AppLocalizations.of(_context).done,
|
|
||||||
style: ThemeUtils.defaultTextStyleInterFont.copyWith(
|
|
||||||
fontSize: 17,
|
|
||||||
color: isValidated
|
|
||||||
? AppColor.colorTextButton
|
|
||||||
: AppColor.colorDisableMailboxCreateButton),
|
|
||||||
),
|
|
||||||
onPressed: () => isValidated ? _onDoneActionClick?.call() : null
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildTitle() {
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
|
||||||
child: Text(
|
|
||||||
title ?? '',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
maxLines: 1,
|
|
||||||
softWrap: CommonTextStyle.defaultSoftWrap,
|
|
||||||
overflow: CommonTextStyle.defaultTextOverFlow,
|
|
||||||
style: ThemeUtils.defaultTextStyleInterFont.copyWith(
|
|
||||||
fontSize: 20,
|
|
||||||
color: AppColor.colorNameEmail,
|
|
||||||
fontWeight: FontWeight.bold)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
import 'package:core/presentation/extensions/color_extension.dart';
|
||||||
|
import 'package:core/presentation/resources/image_paths.dart';
|
||||||
|
import 'package:core/presentation/views/list/tree_view.dart';
|
||||||
|
import 'package:flutter/material.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/utils/mailbox_method_action_define.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/main/localizations/app_localizations.dart';
|
||||||
|
|
||||||
|
class ModalFolderTreeListWidget extends StatelessWidget {
|
||||||
|
|
||||||
|
final MailboxTree defaultTree;
|
||||||
|
final MailboxTree personalTree;
|
||||||
|
final ScrollController listScrollController;
|
||||||
|
final ImagePaths imagePaths;
|
||||||
|
final OnClickOpenMailboxNodeAction onSelectFolderAction;
|
||||||
|
final OnClickExpandMailboxNodeAction onToggleFolderAction;
|
||||||
|
final MailboxId? mailboxIdSelected;
|
||||||
|
|
||||||
|
const ModalFolderTreeListWidget({
|
||||||
|
super.key,
|
||||||
|
required this.defaultTree,
|
||||||
|
required this.personalTree,
|
||||||
|
required this.listScrollController,
|
||||||
|
required this.imagePaths,
|
||||||
|
required this.onSelectFolderAction,
|
||||||
|
required this.onToggleFolderAction,
|
||||||
|
this.mailboxIdSelected,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
physics: const ClampingScrollPhysics(),
|
||||||
|
controller: listScrollController,
|
||||||
|
padding: const EdgeInsetsDirectional.only(end: 14),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
FolderItemWidget(
|
||||||
|
folderName: AppLocalizations.of(context).personalFolders,
|
||||||
|
imagePaths: imagePaths,
|
||||||
|
isSelected: mailboxIdSelected == null,
|
||||||
|
onTapAction: () => onSelectFolderAction(null),
|
||||||
|
),
|
||||||
|
if (defaultTree.root.hasChildren())
|
||||||
|
_buildFolderTree(
|
||||||
|
mailboxTree: defaultTree,
|
||||||
|
mailboxIdSelected: mailboxIdSelected,
|
||||||
|
),
|
||||||
|
if (personalTree.root.hasChildren())
|
||||||
|
_buildFolderTree(
|
||||||
|
mailboxTree: personalTree,
|
||||||
|
mailboxIdSelected: mailboxIdSelected,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
onOpenMailboxFolderClick: onSelectFolderAction,
|
||||||
|
onExpandFolderActionClick: onToggleFolderAction,
|
||||||
|
),
|
||||||
|
children: _buildListChildTileWidget(
|
||||||
|
parentNode: mailboxNode,
|
||||||
|
mailboxIdSelected: mailboxIdSelected,
|
||||||
|
),
|
||||||
|
).build();
|
||||||
|
} else {
|
||||||
|
return MailboxItemWidget(
|
||||||
|
mailboxNode: mailboxNode,
|
||||||
|
mailboxDisplayed: MailboxDisplayed.modalFolder,
|
||||||
|
mailboxIdAlreadySelected: mailboxIdSelected,
|
||||||
|
hoverColor: AppColor.blue100,
|
||||||
|
onOpenMailboxFolderClick: onSelectFolderAction,
|
||||||
|
onExpandFolderActionClick: onToggleFolderAction,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
).toList() ?? [];
|
||||||
|
}
|
||||||
|
}
|
||||||
-1
@@ -272,7 +272,6 @@ class MailboxVisibilityView extends GetWidget<MailboxVisibilityController>
|
|||||||
return parentNode.childrenItems
|
return parentNode.childrenItems
|
||||||
?.map((mailboxNode) => mailboxNode.hasChildren()
|
?.map((mailboxNode) => mailboxNode.hasChildren()
|
||||||
? TreeViewChild(
|
? TreeViewChild(
|
||||||
context,
|
|
||||||
key: const Key('children_tree_mailbox_child'),
|
key: const Key('children_tree_mailbox_child'),
|
||||||
isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND,
|
isExpanded: mailboxNode.expandMode == ExpandMode.EXPAND,
|
||||||
paddingChild: const EdgeInsetsDirectional.only(start: 10),
|
paddingChild: const EdgeInsetsDirectional.only(start: 10),
|
||||||
|
|||||||
@@ -756,12 +756,9 @@ class SearchMailboxController extends BaseMailboxController with MailboxActionHa
|
|||||||
void goToCreateNewMailboxView(BuildContext context, {PresentationMailbox? parentMailbox}) async {
|
void goToCreateNewMailboxView(BuildContext context, {PresentationMailbox? parentMailbox}) async {
|
||||||
if (session != null && accountId != null) {
|
if (session != null && accountId != null) {
|
||||||
final arguments = MailboxCreatorArguments(
|
final arguments = MailboxCreatorArguments(
|
||||||
accountId!,
|
|
||||||
defaultMailboxTree.value,
|
defaultMailboxTree.value,
|
||||||
personalMailboxTree.value,
|
personalMailboxTree.value,
|
||||||
teamMailboxesTree.value,
|
parentMailbox,
|
||||||
session!,
|
|
||||||
parentMailbox
|
|
||||||
);
|
);
|
||||||
|
|
||||||
final result = PlatformInfo.isWeb
|
final result = PlatformInfo.isWeb
|
||||||
|
|||||||
@@ -4789,5 +4789,45 @@
|
|||||||
"type": "text",
|
"type": "text",
|
||||||
"placeholders_order": [],
|
"placeholders_order": [],
|
||||||
"placeholders": {}
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"createANewFolder": "Create a New Folder",
|
||||||
|
"@createANewFolder": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders_order": [],
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"subtitleDisplayTheFolderNameLocationInFolderCreationModal": "New folder will be created inside {folderName}",
|
||||||
|
"@subtitleDisplayTheFolderNameLocationInFolderCreationModal": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders_order": [
|
||||||
|
"folderName"
|
||||||
|
],
|
||||||
|
"placeholders": {
|
||||||
|
"folderName": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"folderName": "Folder Name",
|
||||||
|
"@folderName": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders_order": [],
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"enterTheFolderName": "Enter the folder name",
|
||||||
|
"@enterTheFolderName": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders_order": [],
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"selectTheFolderLocation": "Select the folder location",
|
||||||
|
"@selectTheFolderLocation": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders_order": [],
|
||||||
|
"placeholders": {}
|
||||||
|
},
|
||||||
|
"createFolder": "Create folder",
|
||||||
|
"@createFolder": {
|
||||||
|
"type": "text",
|
||||||
|
"placeholders_order": [],
|
||||||
|
"placeholders": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5059,4 +5059,47 @@ class AppLocalizations {
|
|||||||
name: 'actions',
|
name: 'actions',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get createANewFolder {
|
||||||
|
return Intl.message(
|
||||||
|
'Create a New Folder',
|
||||||
|
name: 'createANewFolder',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String subtitleDisplayTheFolderNameLocationInFolderCreationModal(String folderName) {
|
||||||
|
return Intl.message(
|
||||||
|
'New folder will be created inside $folderName',
|
||||||
|
name: 'subtitleDisplayTheFolderNameLocationInFolderCreationModal',
|
||||||
|
args: [folderName]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String get folderName {
|
||||||
|
return Intl.message(
|
||||||
|
'Folder Name',
|
||||||
|
name: 'folderName',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String get enterTheFolderName {
|
||||||
|
return Intl.message(
|
||||||
|
'Enter the folder name',
|
||||||
|
name: 'enterTheFolderName',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String get selectTheFolderLocation {
|
||||||
|
return Intl.message(
|
||||||
|
'Select the folder location',
|
||||||
|
name: 'selectTheFolderLocation',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String get createFolder {
|
||||||
|
return Intl.message(
|
||||||
|
'Create folder',
|
||||||
|
name: 'createFolder',
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user