Apply new style for create identity view on mobile

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2025-07-11 20:28:29 +07:00
committed by Dat H. Pham
parent 58d22cbc0b
commit fdb062fa3d
4 changed files with 177 additions and 225 deletions
@@ -1,4 +1,3 @@
import 'dart:math' as math;
import 'package:core/presentation/extensions/capitalize_extension.dart'; import 'package:core/presentation/extensions/capitalize_extension.dart';
import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/extensions/color_extension.dart';
@@ -14,8 +13,6 @@ import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/extensions/email_address_extension.dart'; import 'package:model/extensions/email_address_extension.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart'; import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:rich_text_composer/rich_text_composer.dart';
import 'package:rich_text_composer/views/widgets/rich_text_keyboard_toolbar.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_email_address_drop_down_button.dart'; import 'package:tmail_ui_user/features/base/widget/default_field/default_email_address_drop_down_button.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_horizontal_field_widget.dart'; import 'package:tmail_ui_user/features/base/widget/default_field/default_horizontal_field_widget.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_label_field_widget.dart'; import 'package:tmail_ui_user/features/base/widget/default_field/default_label_field_widget.dart';
@@ -68,9 +65,9 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController>
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
semanticLabel: 'Identity input field', semanticLabel: 'Identity input field',
decoration: (IdentityInputDecorationBuilder() decoration: (IdentityInputDecorationBuilder()
..setContentPadding(const EdgeInsets.symmetric( ..setContentPadding(EdgeInsets.symmetric(
horizontal: 12, horizontal: 12,
vertical: 15, vertical: PlatformInfo.isWeb ? 15 : 12,
)) ))
..setErrorText(controller.errorNameIdentity.value) ..setErrorText(controller.errorNameIdentity.value)
..setHintText(appLocalizations.enterName) ..setHintText(appLocalizations.enterName)
@@ -115,9 +112,9 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController>
color: AppColor.m3SurfaceBackground, color: AppColor.m3SurfaceBackground,
), ),
decoration: (IdentityInputDecorationBuilder() decoration: (IdentityInputDecorationBuilder()
..setContentPadding(const EdgeInsets.symmetric( ..setContentPadding(EdgeInsets.symmetric(
horizontal: 12, horizontal: 12,
vertical: 15, vertical: PlatformInfo.isWeb ? 15 : 12,
)) ))
..setErrorText(controller.errorBccIdentity.value) ..setErrorText(controller.errorBccIdentity.value)
..setHintText(appLocalizations.enterEmailAddress) ..setHintText(appLocalizations.enterEmailAddress)
@@ -203,9 +200,9 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController>
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
semanticLabel: 'Identity input field', semanticLabel: 'Identity input field',
decoration: (IdentityInputDecorationBuilder() decoration: (IdentityInputDecorationBuilder()
..setContentPadding(const EdgeInsets.symmetric( ..setContentPadding(EdgeInsets.symmetric(
horizontal: 12, horizontal: 12,
vertical: 15, vertical: PlatformInfo.isWeb ? 15 : 12,
)) ))
..setErrorText(controller.errorNameIdentity.value) ..setErrorText(controller.errorNameIdentity.value)
..setHintText(appLocalizations.enterName) ..setHintText(appLocalizations.enterName)
@@ -256,9 +253,9 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController>
color: AppColor.m3SurfaceBackground, color: AppColor.m3SurfaceBackground,
), ),
decoration: (IdentityInputDecorationBuilder() decoration: (IdentityInputDecorationBuilder()
..setContentPadding(const EdgeInsets.symmetric( ..setContentPadding(EdgeInsets.symmetric(
horizontal: 12, horizontal: 12,
vertical: 15, vertical: PlatformInfo.isWeb ? 15 : 12,
)) ))
..setErrorText(controller.errorBccIdentity.value) ..setErrorText(controller.errorBccIdentity.value)
..setHintText(appLocalizations.enterEmailAddress) ..setHintText(appLocalizations.enterEmailAddress)
@@ -318,132 +315,21 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController>
); );
} }
if (PlatformInfo.isWeb) {
bodyCreatorView = NotificationListener<ScrollNotification>(
onNotification: (scrollInfo) {
if (scrollInfo is ScrollEndNotification &&
scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent) {
controller.clearFocusEditor(context);
}
return false;
},
child: bodyCreatorView,
);
return PointerInterceptor( return PointerInterceptor(
child: ResponsiveWidget( child: ResponsiveWidget(
responsiveUtils: controller.responsiveUtils, responsiveUtils: controller.responsiveUtils,
mobile: IdentityCreatorFormMobileBuilder( mobile: IdentityCreatorFormMobileBuilder(
controller: controller, controller: controller,
formView: bodyCreatorView, formView: bodyCreatorView,
), enableRichTextKeyboard: PlatformInfo.isMobile,
tablet: IdentityCreatorFormDesktopBuilder(
controller: controller,
formView: bodyCreatorView,
)
),
);
} else {
return ResponsiveWidget(
responsiveUtils: controller.responsiveUtils,
mobile: GestureDetector(
onTap: () => controller.clearFocusEditor(context),
child: Scaffold(
backgroundColor: Colors.black38,
body: SafeArea(
bottom: false,
child: KeyboardRichText(
keyBroadToolbar: RichTextKeyboardToolBar(
rootContext: context,
titleBack: AppLocalizations.of(context).titleFormat,
backgroundKeyboardToolBarColor: PlatformInfo.isIOS
? AppColor.colorBackgroundKeyboard
: AppColor.colorBackgroundKeyboardAndroid,
richTextController: controller.richTextMobileTabletController!.richTextController,
quickStyleLabel: AppLocalizations.of(context).titleQuickStyles,
backgroundLabel: AppLocalizations.of(context).titleBackground,
foregroundLabel: AppLocalizations.of(context).titleForeground,
formatLabel: AppLocalizations.of(context).titleFormat,
insertImage: () => controller.pickImage(context),
),
richTextController: controller.richTextMobileTabletController!.richTextController,
child: Card(
margin: EdgeInsets.zero,
elevation: 16,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topRight: Radius.circular(16),
topLeft: Radius.circular(16)
),
),
clipBehavior: Clip.antiAlias,
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topRight: Radius.circular(16),
topLeft: Radius.circular(16)
),
),
child: Column(children: [
Expanded(child: bodyCreatorView)
]),
),
),
),
),
),
), ),
tablet: Portal( tablet: Portal(
child: GestureDetector( child: IdentityCreatorFormDesktopBuilder(
onTap: () => controller.clearFocusEditor(context), controller: controller,
child: Scaffold( formView: bodyCreatorView,
backgroundColor: Colors.black38,
body: SafeArea(
child: KeyboardRichText(
keyBroadToolbar: RichTextKeyboardToolBar(
rootContext: context,
titleBack: AppLocalizations.of(context).titleFormat,
backgroundKeyboardToolBarColor: PlatformInfo.isIOS
? AppColor.colorBackgroundKeyboard
: AppColor.colorBackgroundKeyboardAndroid,
richTextController: controller.richTextMobileTabletController!.richTextController,
quickStyleLabel: AppLocalizations.of(context).titleQuickStyles,
backgroundLabel: AppLocalizations.of(context).titleBackground,
foregroundLabel: AppLocalizations.of(context).titleForeground,
formatLabel: AppLocalizations.of(context).titleFormat,
insertImage: () => controller.pickImage(context),
),
richTextController: controller.richTextMobileTabletController!.richTextController,
child: Center(
child: Padding(
padding: const EdgeInsetsDirectional.symmetric(horizontal: 24),
child: Card(
color: Colors.transparent,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(16))
),
clipBehavior: Clip.antiAlias,
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(16))
),
width: math.max(controller.responsiveUtils.getSizeScreenWidth(context) * 0.4, 700),
height: controller.responsiveUtils.getSizeScreenHeight(context) * 0.8,
child: Column(children: [
Expanded(child: bodyCreatorView),
])
)
),
)
), ),
), ),
), ),
),
),
)
); );
} }
} }
}
@@ -23,8 +23,7 @@ class IdentityCreatorFormBottomView extends StatelessWidget {
final checkboxWidget = Obx(() { final checkboxWidget = Obx(() {
if (controller.isDefaultIdentitySupported.isTrue) { if (controller.isDefaultIdentitySupported.isTrue) {
return Expanded( return Obx(() {
child: Obx(() {
return CustomIconLabeledCheckbox( return CustomIconLabeledCheckbox(
label: appLocalizations.setDefaultIdentity, label: appLocalizations.setDefaultIdentity,
svgIconPath: controller.imagePaths.icCheckboxUnselected, svgIconPath: controller.imagePaths.icCheckboxUnselected,
@@ -33,8 +32,7 @@ class IdentityCreatorFormBottomView extends StatelessWidget {
semanticsLabel: 'Set default identity checkbox', semanticsLabel: 'Set default identity checkbox',
onChanged: (_) => controller.onCheckboxChanged(), onChanged: (_) => controller.onCheckboxChanged(),
); );
}), });
);
} else { } else {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
@@ -113,7 +111,7 @@ class IdentityCreatorFormBottomView extends StatelessWidget {
), ),
child: Row( child: Row(
children: [ children: [
checkboxWidget, Expanded(child: checkboxWidget),
Expanded( Expanded(
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
@@ -1,7 +1,11 @@
import 'dart:math'; import 'dart:math';
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:rich_text_composer/views/keyboard_rich_text.dart';
import 'package:rich_text_composer/views/widgets/rich_text_keyboard_toolbar.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_close_button_widget.dart'; import 'package:tmail_ui_user/features/base/widget/default_field/default_close_button_widget.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_controller.dart'; import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_controller.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_creator_form_bottom_view.dart'; import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_creator_form_bottom_view.dart';
@@ -11,23 +15,20 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class IdentityCreatorFormDesktopBuilder extends StatelessWidget { class IdentityCreatorFormDesktopBuilder extends StatelessWidget {
final IdentityCreatorController controller; final IdentityCreatorController controller;
final Widget formView; final Widget formView;
final bool enableRichTextKeyboard;
const IdentityCreatorFormDesktopBuilder({ const IdentityCreatorFormDesktopBuilder({
super.key, super.key,
required this.controller, required this.controller,
required this.formView, required this.formView,
this.enableRichTextKeyboard = false,
}); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final appLocalizations = AppLocalizations.of(context); final appLocalizations = AppLocalizations.of(context);
return Scaffold( Widget bodyWidget = Container(
backgroundColor: Colors.black.withOpacity(0.2),
body: GestureDetector(
onTap: () => controller.clearFocusEditor(context),
child: Center(
child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.white,
borderRadius: const BorderRadius.all(Radius.circular(16)), borderRadius: const BorderRadius.all(Radius.circular(16)),
@@ -69,8 +70,41 @@ class IdentityCreatorFormDesktopBuilder extends StatelessWidget {
), ),
], ],
), ),
);
if (enableRichTextKeyboard) {
final richTextController = controller
.richTextMobileTabletController
!.richTextController;
bodyWidget = KeyboardRichText(
keyBroadToolbar: RichTextKeyboardToolBar(
rootContext: context,
titleBack: appLocalizations.titleFormat,
backgroundKeyboardToolBarColor: PlatformInfo.isIOS
? AppColor.colorBackgroundKeyboard
: AppColor.colorBackgroundKeyboardAndroid,
richTextController: richTextController,
quickStyleLabel: appLocalizations.titleQuickStyles,
backgroundLabel: appLocalizations.titleBackground,
foregroundLabel: appLocalizations.titleForeground,
formatLabel: appLocalizations.titleFormat,
insertImage: () => controller.pickImage(context),
), ),
), richTextController: richTextController,
child: bodyWidget,
);
}
if (PlatformInfo.isMobile) {
bodyWidget = SafeArea(child: bodyWidget);
}
return Scaffold(
backgroundColor: Colors.black.withOpacity(0.2),
body: GestureDetector(
onTap: () => controller.clearFocusEditor(context),
child: Center(child: bodyWidget),
), ),
); );
} }
@@ -1,5 +1,9 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/utils/platform_info.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:rich_text_composer/rich_text_composer.dart';
import 'package:rich_text_composer/views/widgets/rich_text_keyboard_toolbar.dart';
import 'package:tmail_ui_user/features/base/widget/default_field/default_app_bar_widget.dart'; import 'package:tmail_ui_user/features/base/widget/default_field/default_app_bar_widget.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_controller.dart'; import 'package:tmail_ui_user/features/identity_creator/presentation/identity_creator_controller.dart';
import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_creator_form_bottom_view.dart'; import 'package:tmail_ui_user/features/identity_creator/presentation/widgets/identity_creator_form_bottom_view.dart';
@@ -8,23 +12,20 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class IdentityCreatorFormMobileBuilder extends StatelessWidget { class IdentityCreatorFormMobileBuilder extends StatelessWidget {
final IdentityCreatorController controller; final IdentityCreatorController controller;
final Widget formView; final Widget formView;
final bool enableRichTextKeyboard;
const IdentityCreatorFormMobileBuilder({ const IdentityCreatorFormMobileBuilder({
super.key, super.key,
required this.controller, required this.controller,
required this.formView, required this.formView,
this.enableRichTextKeyboard = false,
}); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final appLocalizations = AppLocalizations.of(context); final appLocalizations = AppLocalizations.of(context);
return Scaffold( Widget bodyWidget = ColoredBox(
backgroundColor: Colors.white,
body: GestureDetector(
onTap: () => controller.clearFocusEditor(context),
child: SafeArea(
child: ColoredBox(
color: Colors.white, color: Colors.white,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@@ -54,8 +55,41 @@ class IdentityCreatorFormMobileBuilder extends StatelessWidget {
), ),
], ],
), ),
);
if (enableRichTextKeyboard) {
final richTextController = controller
.richTextMobileTabletController
!.richTextController;
bodyWidget = KeyboardRichText(
keyBroadToolbar: RichTextKeyboardToolBar(
rootContext: context,
titleBack: appLocalizations.titleFormat,
backgroundKeyboardToolBarColor: PlatformInfo.isIOS
? AppColor.colorBackgroundKeyboard
: AppColor.colorBackgroundKeyboardAndroid,
richTextController: richTextController,
quickStyleLabel: appLocalizations.titleQuickStyles,
backgroundLabel: appLocalizations.titleBackground,
foregroundLabel: appLocalizations.titleForeground,
formatLabel: appLocalizations.titleFormat,
insertImage: () => controller.pickImage(context),
), ),
), richTextController: richTextController,
child: bodyWidget,
);
}
if (PlatformInfo.isMobile) {
bodyWidget = SafeArea(child: bodyWidget);
}
return Scaffold(
backgroundColor: Colors.white,
body: GestureDetector(
onTap: () => controller.clearFocusEditor(context),
child: bodyWidget,
), ),
); );
} }