From 0b3f72915a42d14b761aea7cf5b410c34f1a97f0 Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 6 Sep 2023 11:52:49 +0700 Subject: [PATCH] TF-2116 Create ContainerViewComposer for all platform on web (cherry picked from commit d034974d854cdeda5cfaebaa823b977fbd8fc819) --- .../styles/desktop_container_view_style.dart | 11 +++ .../minimize_composer_widget_style.dart | 16 +++ .../styles/mobile_container_view_style.dart | 8 ++ .../styles/tablet_container_view_style.dart | 34 +++++++ .../view/desktop_container_view.dart | 97 +++++++++++++++++++ .../view/mobile_container_view.dart | 25 +++++ .../view/tablet_container_view.dart | 43 ++++++++ .../widgets/minimize_composer_widget.dart | 90 +++++++++++++++++ 8 files changed, 324 insertions(+) create mode 100644 lib/features/composer/presentation/styles/desktop_container_view_style.dart create mode 100644 lib/features/composer/presentation/styles/minimize_composer_widget_style.dart create mode 100644 lib/features/composer/presentation/styles/mobile_container_view_style.dart create mode 100644 lib/features/composer/presentation/styles/tablet_container_view_style.dart create mode 100644 lib/features/composer/presentation/view/desktop_container_view.dart create mode 100644 lib/features/composer/presentation/view/mobile_container_view.dart create mode 100644 lib/features/composer/presentation/view/tablet_container_view.dart create mode 100644 lib/features/composer/presentation/widgets/minimize_composer_widget.dart diff --git a/lib/features/composer/presentation/styles/desktop_container_view_style.dart b/lib/features/composer/presentation/styles/desktop_container_view_style.dart new file mode 100644 index 000000000..1ecc1a4ca --- /dev/null +++ b/lib/features/composer/presentation/styles/desktop_container_view_style.dart @@ -0,0 +1,11 @@ + +import 'package:flutter/material.dart'; + +class DesktopContainerViewStyle { + static const double radius = 28; + static const double margin = 20; + static const double elevation = 16; + + static const Color backgroundColor = Colors.white; + static const Color outSideBackgroundColor = Colors.black38; +} \ No newline at end of file diff --git a/lib/features/composer/presentation/styles/minimize_composer_widget_style.dart b/lib/features/composer/presentation/styles/minimize_composer_widget_style.dart new file mode 100644 index 000000000..a41d7e5d5 --- /dev/null +++ b/lib/features/composer/presentation/styles/minimize_composer_widget_style.dart @@ -0,0 +1,16 @@ +import 'package:flutter/material.dart'; + +class MinimizeComposerWidgetStyle { + static const double radius = 24; + static const double elevation = 16; + static const double width = 500; + static const double height = 50; + static const double space = 8; + static const double iconSize = 20; + + static const Color backgroundColor = Colors.white; + static const Color iconColor = Colors.black; + + static const EdgeInsetsGeometry padding = EdgeInsetsDirectional.symmetric(horizontal: 24); + static const EdgeInsetsGeometry iconPadding = EdgeInsetsDirectional.all(3); +} \ No newline at end of file diff --git a/lib/features/composer/presentation/styles/mobile_container_view_style.dart b/lib/features/composer/presentation/styles/mobile_container_view_style.dart new file mode 100644 index 000000000..928a72dad --- /dev/null +++ b/lib/features/composer/presentation/styles/mobile_container_view_style.dart @@ -0,0 +1,8 @@ +import 'package:flutter/material.dart'; + +class MobileContainerViewStyle { + static const double radius = 28; + static const double elevation = 16; + + static const Color outSideBackgroundColor = Colors.white; +} \ No newline at end of file diff --git a/lib/features/composer/presentation/styles/tablet_container_view_style.dart b/lib/features/composer/presentation/styles/tablet_container_view_style.dart new file mode 100644 index 000000000..3421c420e --- /dev/null +++ b/lib/features/composer/presentation/styles/tablet_container_view_style.dart @@ -0,0 +1,34 @@ + +import 'package:core/presentation/utils/responsive_utils.dart'; +import 'package:flutter/material.dart'; + +class TabletContainerViewStyle { + static const double radius = 28; + static const double elevation = 16; + + static const Color backgroundColor = Colors.white; + static const Color outSideBackgroundColor = Colors.black38; + + static EdgeInsetsGeometry getMargin( + BuildContext context, + ResponsiveUtils responsiveUtils + ) { + if (responsiveUtils.isTablet(context)) { + return const EdgeInsetsDirectional.all(24); + } else { + return const EdgeInsetsDirectional.symmetric(vertical: 24); + } + } + + static double getWidth( + BuildContext context, + ResponsiveUtils responsiveUtils + ) { + final currentWidth = responsiveUtils.getSizeScreenWidth(context); + if (responsiveUtils.isTablet(context)) { + return currentWidth; + } else { + return currentWidth * 0.7; + } + } +} \ No newline at end of file diff --git a/lib/features/composer/presentation/view/desktop_container_view.dart b/lib/features/composer/presentation/view/desktop_container_view.dart new file mode 100644 index 000000000..f0367cfa3 --- /dev/null +++ b/lib/features/composer/presentation/view/desktop_container_view.dart @@ -0,0 +1,97 @@ +import 'package:core/presentation/utils/responsive_utils.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:pointer_interceptor/pointer_interceptor.dart'; +import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart'; +import 'package:tmail_ui_user/features/composer/presentation/styles/desktop_container_view_style.dart'; +import 'package:tmail_ui_user/features/composer/presentation/widgets/minimize_composer_widget.dart'; + +class DesktopContainerView extends StatelessWidget { + + final ScreenDisplayMode displayMode; + final String emailSubject; + final VoidCallback onCloseViewAction; + final OnChangeDisplayModeAction onChangeDisplayModeAction; + final Widget Function(BuildContext context, BoxConstraints constraints) childBuilder; + + final _responsiveUtils = Get.find(); + + DesktopContainerView({ + super.key, + required this.childBuilder, + required this.displayMode, + required this.emailSubject, + required this.onCloseViewAction, + required this.onChangeDisplayModeAction, + }); + + @override + Widget build(BuildContext context) { + if (displayMode == ScreenDisplayMode.minimize) { + return PositionedDirectional( + end: DesktopContainerViewStyle.margin, + bottom: DesktopContainerViewStyle.margin, + child: PointerInterceptor( + child: MinimizeComposerWidget( + emailSubject: emailSubject, + onCloseViewAction: onCloseViewAction, + onChangeDisplayModeAction: onChangeDisplayModeAction, + ), + ) + ); + } else if (displayMode == ScreenDisplayMode.normal) { + final maxWidth = _responsiveUtils.getSizeScreenWidth(context) * 0.5; + final maxHeight = _responsiveUtils.getSizeScreenHeight(context) * 0.75; + + return PositionedDirectional( + end: DesktopContainerViewStyle.margin, + bottom: DesktopContainerViewStyle.margin, + child: Card( + elevation: DesktopContainerViewStyle.elevation, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(DesktopContainerViewStyle.radius)) + ), + clipBehavior: Clip.antiAlias, + child: Container( + color: DesktopContainerViewStyle.backgroundColor, + width: maxWidth, + height: maxHeight, + child: LayoutBuilder(builder: (context, constraints) => + PointerInterceptor( + child: childBuilder.call(context, constraints) + ) + ) + ), + ) + ); + } else if (displayMode == ScreenDisplayMode.fullScreen) { + final maxWidth = _responsiveUtils.getSizeScreenWidth(context) * 0.85; + final maxHeight = _responsiveUtils.getSizeScreenHeight(context) * 0.9; + + return Scaffold( + backgroundColor: DesktopContainerViewStyle.outSideBackgroundColor, + body: Center( + child: Card( + elevation: DesktopContainerViewStyle.elevation, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(DesktopContainerViewStyle.radius)) + ), + clipBehavior: Clip.antiAlias, + child: Container( + color: DesktopContainerViewStyle.backgroundColor, + width: maxWidth, + height: maxHeight, + child: LayoutBuilder(builder: (context, constraints) => + PointerInterceptor( + child: childBuilder.call(context, constraints) + ) + ) + ), + ), + ) + ); + } else { + return const SizedBox.shrink(); + } + } +} \ No newline at end of file diff --git a/lib/features/composer/presentation/view/mobile_container_view.dart b/lib/features/composer/presentation/view/mobile_container_view.dart new file mode 100644 index 000000000..07671d40c --- /dev/null +++ b/lib/features/composer/presentation/view/mobile_container_view.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; +import 'package:pointer_interceptor/pointer_interceptor.dart'; +import 'package:tmail_ui_user/features/composer/presentation/styles/mobile_container_view_style.dart'; + +class MobileContainerView extends StatelessWidget { + + final Widget Function(BuildContext context, BoxConstraints constraints) childBuilder; + + const MobileContainerView({ + super.key, + required this.childBuilder, + }); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: MobileContainerViewStyle.outSideBackgroundColor, + body: LayoutBuilder(builder: (context, constraints) => + PointerInterceptor( + child: childBuilder.call(context, constraints) + ) + ) + ); + } +} \ No newline at end of file diff --git a/lib/features/composer/presentation/view/tablet_container_view.dart b/lib/features/composer/presentation/view/tablet_container_view.dart new file mode 100644 index 000000000..27ce6e54b --- /dev/null +++ b/lib/features/composer/presentation/view/tablet_container_view.dart @@ -0,0 +1,43 @@ +import 'package:core/presentation/utils/responsive_utils.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:pointer_interceptor/pointer_interceptor.dart'; +import 'package:tmail_ui_user/features/composer/presentation/styles/tablet_container_view_style.dart'; + +class TabletContainerView extends StatelessWidget { + + final Widget Function(BuildContext context, BoxConstraints constraints) childBuilder; + + final _responsiveUtils = Get.find(); + + TabletContainerView({ + super.key, + required this.childBuilder, + }); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: TabletContainerViewStyle.outSideBackgroundColor, + body: Center( + child: Card( + elevation: TabletContainerViewStyle.elevation, + margin: TabletContainerViewStyle.getMargin(context, _responsiveUtils), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(TabletContainerViewStyle.radius)) + ), + clipBehavior: Clip.antiAlias, + child: Container( + color: TabletContainerViewStyle.backgroundColor, + width: TabletContainerViewStyle.getWidth(context, _responsiveUtils), + child: LayoutBuilder(builder: (context, constraints) => + PointerInterceptor( + child: childBuilder.call(context, constraints) + ) + ) + ), + ), + ) + ); + } +} \ No newline at end of file diff --git a/lib/features/composer/presentation/widgets/minimize_composer_widget.dart b/lib/features/composer/presentation/widgets/minimize_composer_widget.dart new file mode 100644 index 000000000..6aa9d61fc --- /dev/null +++ b/lib/features/composer/presentation/widgets/minimize_composer_widget.dart @@ -0,0 +1,90 @@ +import 'package:core/presentation/resources/image_paths.dart'; +import 'package:core/presentation/views/button/tmail_button_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:tmail_ui_user/features/composer/presentation/model/screen_display_mode.dart'; +import 'package:tmail_ui_user/features/composer/presentation/styles/minimize_composer_widget_style.dart'; +import 'package:tmail_ui_user/features/composer/presentation/widgets/title_composer_widget.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +typedef OnChangeDisplayModeAction = Function(ScreenDisplayMode mode); + +class MinimizeComposerWidget extends StatelessWidget { + + final OnChangeDisplayModeAction onChangeDisplayModeAction; + final VoidCallback onCloseViewAction; + final String emailSubject; + + final _imagePaths = Get.find(); + + MinimizeComposerWidget({ + super.key, + required this.emailSubject, + required this.onChangeDisplayModeAction, + required this.onCloseViewAction, + }); + + @override + Widget build(BuildContext context) { + return Card( + elevation: MinimizeComposerWidgetStyle.elevation, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(MinimizeComposerWidgetStyle.radius)) + ), + clipBehavior: Clip.antiAlias, + child: Container( + color: MinimizeComposerWidgetStyle.backgroundColor, + width: MinimizeComposerWidgetStyle.width, + height: MinimizeComposerWidgetStyle.height, + padding: MinimizeComposerWidgetStyle.padding, + child: Stack( + children: [ + Center( + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: MinimizeComposerWidgetStyle.width / 2), + child: TitleComposerWidget(emailSubject: emailSubject), + ), + ), + Align( + alignment: AlignmentDirectional.centerStart, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + TMailButtonWidget.fromIcon( + icon: _imagePaths.icCancel, + backgroundColor: Colors.transparent, + tooltipMessage: AppLocalizations.of(context).saveAndClose, + iconSize: MinimizeComposerWidgetStyle.iconSize, + iconColor: MinimizeComposerWidgetStyle.iconColor, + padding: MinimizeComposerWidgetStyle.iconPadding, + onTapActionCallback: onCloseViewAction + ), + const SizedBox(width: MinimizeComposerWidgetStyle.space), + TMailButtonWidget.fromIcon( + icon: _imagePaths.icFullScreen, + backgroundColor: Colors.transparent, + tooltipMessage: AppLocalizations.of(context).fullscreen, + iconSize: MinimizeComposerWidgetStyle.iconSize, + iconColor: MinimizeComposerWidgetStyle.iconColor, + padding: MinimizeComposerWidgetStyle.iconPadding, + onTapActionCallback: () => onChangeDisplayModeAction(ScreenDisplayMode.fullScreen) + ), + const SizedBox(width: MinimizeComposerWidgetStyle.space), + TMailButtonWidget.fromIcon( + icon: _imagePaths.icChevronUp, + backgroundColor: Colors.transparent, + tooltipMessage: AppLocalizations.of(context).show, + iconSize: MinimizeComposerWidgetStyle.iconSize, + iconColor: MinimizeComposerWidgetStyle.iconColor, + padding: MinimizeComposerWidgetStyle.iconPadding, + onTapActionCallback: () => onChangeDisplayModeAction(ScreenDisplayMode.normal) + ), + ] + ), + ) + ], + ) + ), + ); + } +} \ No newline at end of file