diff --git a/lib/features/destination_picker/presentation/destination_picker_controller.dart b/lib/features/destination_picker/presentation/destination_picker_controller.dart index d6be31835..f4c9d9bf8 100644 --- a/lib/features/destination_picker/presentation/destination_picker_controller.dart +++ b/lib/features/destination_picker/presentation/destination_picker_controller.dart @@ -112,6 +112,8 @@ class DestinationPickerController extends BaseMailboxController { mailboxCategoriesExpandMode.value.folderMailbox = newExpandMode; mailboxCategoriesExpandMode.refresh(); break; + default: + return; } } diff --git a/lib/features/mailbox/presentation/mailbox_controller.dart b/lib/features/mailbox/presentation/mailbox_controller.dart index 8edc615b6..81a9327a8 100644 --- a/lib/features/mailbox/presentation/mailbox_controller.dart +++ b/lib/features/mailbox/presentation/mailbox_controller.dart @@ -30,6 +30,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/model/rename_mailbox_reque import 'package:tmail_ui_user/features/mailbox/domain/state/create_new_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/delete_multiple_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/get_all_mailboxes_state.dart'; +import 'package:tmail_ui_user/features/mailbox/domain/state/mark_as_mailbox_read_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/move_mailbox_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/refresh_changes_all_mailboxes_state.dart'; import 'package:tmail_ui_user/features/mailbox/domain/state/rename_mailbox_state.dart'; @@ -54,7 +55,6 @@ 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/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/domain/state/mark_as_mailbox_read_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/remove_email_drafts_state.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart'; @@ -848,9 +848,21 @@ class MailboxController extends BaseMailboxController { mailboxCategoriesExpandMode.value.folderMailbox = newExpandMode; mailboxCategoriesExpandMode.refresh(); break; + case MailboxCategories.appGrid: + final currentExpandMode = mailboxDashBoardController.appGridDashboardController.appDashboardExpandMode.value; + if (currentExpandMode == ExpandMode.COLLAPSE) { + _showAppDashboardAction(); + } else { + mailboxDashBoardController.appGridDashboardController.toggleAppGridDashboard(); + } + break; } } + void _showAppDashboardAction() { + mailboxDashBoardController.showAppDashboardAction(); + } + void handleMailboxAction(BuildContext context, MailboxActions actions, PresentationMailbox mailbox) { popBack(); diff --git a/lib/features/mailbox/presentation/mailbox_view_web.dart b/lib/features/mailbox/presentation/mailbox_view_web.dart index b03321ff7..1c3985eab 100644 --- a/lib/features/mailbox/presentation/mailbox_view_web.dart +++ b/lib/features/mailbox/presentation/mailbox_view_web.dart @@ -16,8 +16,10 @@ import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_bott import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_folder_tile_builder.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/widgets/mailbox_search_tile_builder.dart'; import 'package:tmail_ui_user/features/mailbox/presentation/widgets/user_information_widget_builder.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/widgets/app_dashboard/app_list_dashboard_item.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/utils/app_config.dart'; class MailboxView extends GetWidget with AppLoaderMixin, PopupMenuWidgetMixin { @@ -159,6 +161,12 @@ class MailboxView extends GetWidget with AppLoaderMixin, Popu return _buildUserInformation(context); }), _buildLoadingView(), + AppConfig.appGridDashboardAvailable && _responsiveUtils.isWebNotDesktop(context) + ? _buildAppGridDashboard(context) + : const SizedBox.shrink(), + const SizedBox(height: 8), + const Divider(color: AppColor.colorDividerMailbox, height: 0.5, thickness: 0.2), + const SizedBox(height: 8), Obx(() => controller.defaultMailboxHasChild ? _buildMailboxCategory(context, MailboxCategories.exchange, controller.defaultRootNode) : const SizedBox.shrink()), @@ -467,4 +475,90 @@ class MailboxView extends GetWidget with AppLoaderMixin, Popu ), )); } + + Widget _buildAppGridDashboard(BuildContext context) { + return Column( + children: [ + _buildGoToApplicationsCategory(context, MailboxCategories.appGrid), + AnimatedContainer( + padding: const EdgeInsets.only(top: 8), + duration: const Duration(milliseconds: 400), + child: controller.mailboxDashBoardController.appGridDashboardController.appDashboardExpandMode.value == ExpandMode.EXPAND + ? _buildAppGridInMailboxView(context) + : const Offstage()) + ]); + } + + Widget _buildGoToApplicationsCategory(BuildContext context, MailboxCategories categories) { + return Padding( + padding: EdgeInsets.only( + top: 8, + left: _responsiveUtils.isDesktop(context) ? 0 : 36, + right: _responsiveUtils.isDesktop(context) ? 0 : 28 + ), + child: Row( + children: [ + buildIconWeb( + splashRadius: 5, + iconPadding: EdgeInsets.zero, + minSize: 12, + iconSize: 28, + icon: SvgPicture.asset( + _imagePaths.icAppDashboard, + color: AppColor.primaryColor, + fit: BoxFit.fill + ), + tooltip: AppLocalizations.of(context).appGridTittle), + Expanded( + child: Padding( + padding: const EdgeInsets.only(left: 12), + child: Text(categories.getTitle(context), + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontSize: 16, + color: AppColor.colorTextButton, + fontWeight: FontWeight.w500 + ) + ) + ) + ), + buildIconWeb( + splashRadius: 5, + iconPadding: EdgeInsets.zero, + minSize: 12, + iconSize: 28, + icon: Obx(() => SvgPicture.asset( + controller.mailboxDashBoardController.appGridDashboardController.appDashboardExpandMode.value == ExpandMode.COLLAPSE + ? _imagePaths.icCollapseFolder + : _imagePaths.icExpandFolder, + color: AppColor.primaryColor, + fit: BoxFit.fill + )), + tooltip: AppLocalizations.of(context).appGridTittle, + onTap: () => controller.toggleMailboxCategories(categories) + ), + ] + ) + ); + } + + Widget _buildAppGridInMailboxView(BuildContext context) { + return Obx(() { + final linagoraApps = controller.mailboxDashBoardController.appGridDashboardController.linagoraApplications.value; + if (linagoraApps != null && linagoraApps.apps.isNotEmpty) { + return ListView.separated( + shrinkWrap: true, + itemCount: linagoraApps.apps.length, + itemBuilder: (context, index) { + return AppListDashboardItem(linagoraApps.apps[index]); + }, + separatorBuilder: (context, index) { + return const SizedBox.shrink(); + }, + ); + } + return const SizedBox.shrink(); + }); + } } \ No newline at end of file diff --git a/lib/features/mailbox/presentation/model/mailbox_categories.dart b/lib/features/mailbox/presentation/model/mailbox_categories.dart index ba397bfa5..2fe65434e 100644 --- a/lib/features/mailbox/presentation/model/mailbox_categories.dart +++ b/lib/features/mailbox/presentation/model/mailbox_categories.dart @@ -7,6 +7,7 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; enum MailboxCategories { exchange, folders, + appGrid, } extension MailboxCategoriessExtension on MailboxCategories { @@ -17,6 +18,8 @@ extension MailboxCategoriessExtension on MailboxCategories { return 'exchange'; case MailboxCategories.folders: return 'folders'; + case MailboxCategories.appGrid: + return 'appGrid'; } } @@ -26,6 +29,8 @@ extension MailboxCategoriessExtension on MailboxCategories { return AppLocalizations.of(context).exchange; case MailboxCategories.folders: return AppLocalizations.of(context).myFolders; + case MailboxCategories.appGrid: + return AppLocalizations.of(context).appGridTittle; } } @@ -35,6 +40,8 @@ extension MailboxCategoriessExtension on MailboxCategories { return categoriesExpandMode.defaultMailbox; case MailboxCategories.folders: return categoriesExpandMode.folderMailbox; + default: + return ExpandMode.COLLAPSE; } } } \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/presentation/controller/app_grid_dashboard_controller.dart b/lib/features/mailbox_dashboard/presentation/controller/app_grid_dashboard_controller.dart index 974fe3ef5..bb6c7317c 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/app_grid_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/app_grid_dashboard_controller.dart @@ -3,12 +3,14 @@ import 'package:core/presentation/state/success.dart'; import 'package:core/utils/app_logger.dart'; import 'package:dartz/dartz.dart'; import 'package:get/get_rx/get_rx.dart'; +import 'package:model/mailbox/expand_mode.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/app_dashboard/linagora_applications.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_app_dashboard_configuration_interactor.dart'; import 'package:tmail_ui_user/main/utils/app_config.dart'; class AppGridDashboardController { final isAppGridDashboardOverlayOpen = false.obs; + final appDashboardExpandMode = ExpandMode.COLLAPSE.obs; final linagoraApplications = Rxn(); final GetAppDashboardConfigurationInteractor _getAppDashboardConfigurationInteractor; @@ -17,6 +19,10 @@ class AppGridDashboardController { void toggleAppGridDashboard() { isAppGridDashboardOverlayOpen.toggle(); + final newExpandMode = appDashboardExpandMode.value == ExpandMode.EXPAND + ? ExpandMode.COLLAPSE + : ExpandMode.EXPAND; + appDashboardExpandMode.value = newExpandMode; } Stream> showDashboardAction() { @@ -26,6 +32,7 @@ class AppGridDashboardController { void handleShowAppDashboard(LinagoraApplications linagoraApps) { log('AppGridDashboardController::handleShowAppDashboard(): $linagoraApps'); isAppGridDashboardOverlayOpen.value = true; + appDashboardExpandMode.value = ExpandMode.EXPAND; linagoraApplications.value = linagoraApps; } } \ No newline at end of file diff --git a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart index be1f21ec6..e62b42e7d 100644 --- a/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart +++ b/lib/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart @@ -89,8 +89,8 @@ class MailboxDashBoardController extends ReloadableController { final EmailReceiveManager _emailReceiveManager = Get.find(); final SearchController searchController = Get.find(); final DownloadController downloadController = Get.find(); - final AppGridDashboardController _appGridDashboardController = Get.find(); final NetworkConnectionController networkConnectionController = Get.find(); + final AppGridDashboardController appGridDashboardController = Get.find(); final MoveToMailboxInteractor _moveToMailboxInteractor; final DeleteEmailPermanentlyInteractor _deleteEmailPermanentlyInteractor; @@ -275,7 +275,7 @@ class MailboxDashBoardController extends ReloadableController { || success is DeleteMultipleEmailsPermanentlyHasSomeEmailFailure) { _deleteMultipleEmailsPermanentlySuccess(success); } else if (success is GetAppDashboardConfigurationSuccess) { - _appGridDashboardController.handleShowAppDashboard(success.linagoraApplications); + appGridDashboardController.handleShowAppDashboard(success.linagoraApplications); } } ); @@ -1123,12 +1123,13 @@ class MailboxDashBoardController extends ReloadableController { } void showAppDashboardAction() async { - final apps = _appGridDashboardController.linagoraApplications.value; + log('MailboxDashBoardController::showAppDashboardAction(): begin'); + final apps = appGridDashboardController.linagoraApplications.value; if (apps != null) { consumeState(Stream.value(Right(GetAppDashboardConfigurationSuccess(apps)))); return; } - consumeState(_appGridDashboardController.showDashboardAction()); + consumeState(appGridDashboardController.showDashboardAction()); } @override diff --git a/lib/features/mailbox_dashboard/presentation/widgets/app_dashboard/app_grid_dashboard_item.dart b/lib/features/mailbox_dashboard/presentation/widgets/app_dashboard/app_grid_dashboard_item.dart index 6d66d6932..5a218406e 100644 --- a/lib/features/mailbox_dashboard/presentation/widgets/app_dashboard/app_grid_dashboard_item.dart +++ b/lib/features/mailbox_dashboard/presentation/widgets/app_dashboard/app_grid_dashboard_item.dart @@ -7,8 +7,6 @@ import 'package:get/get.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/domain/app_dashboard/linagora_app.dart'; import 'package:url_launcher/url_launcher.dart' as launcher; -typedef OnTapCallback = void Function(); - class AppGridDashboardItem extends StatelessWidget { final LinagoraApp app; diff --git a/lib/features/mailbox_dashboard/presentation/widgets/app_dashboard/app_list_dashboard_item.dart b/lib/features/mailbox_dashboard/presentation/widgets/app_dashboard/app_list_dashboard_item.dart new file mode 100644 index 000000000..6abc7b04e --- /dev/null +++ b/lib/features/mailbox_dashboard/presentation/widgets/app_dashboard/app_list_dashboard_item.dart @@ -0,0 +1,76 @@ +import 'package:core/core.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get_core/get_core.dart'; +import 'package:get/get_instance/get_instance.dart'; +import 'package:tmail_ui_user/features/mailbox_dashboard/domain/app_dashboard/linagora_app.dart'; +import 'package:url_launcher/url_launcher.dart' as launcher; + +class AppListDashboardItem extends StatefulWidget { + final LinagoraApp app; + + const AppListDashboardItem(this.app, {Key? key}) : super(key: key); + + @override + State createState() => _AppListDashboardItemState(); +} + +class _AppListDashboardItemState extends State { + final _imagePaths = Get.find(); + final _responsiveUtils = Get.find(); + bool _isHoverItem = false; + + @override + Widget build(BuildContext context) { + return StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + return InkWell( + onTap: () => _openApp(widget.app.appUri), + onHover: (value) => setState(() => _isHoverItem = value), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: _backgroundColorItem(context)), + padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 18), + margin: const EdgeInsets.symmetric(horizontal: 16), + child: _buildAppItem(context) + ), + ); + } + ); + } + + Widget _buildAppItem(BuildContext context) { + final builder = SloganBuilder(arrangedByHorizontal: true) + ..setSizeLogo(32.0) + ..setPadding(const EdgeInsets.only(left: 12)) + ..setSloganText(widget.app.appName) + ..addOnTapCallback(() async { + final url = widget.app.appUri; + if (await launcher.canLaunchUrl(url)) { + await launcher.launchUrl(url); + } + }) + ..setSloganTextStyle(const TextStyle(fontSize: 17, fontWeight: FontWeight.w500, color: AppColor.colorNameEmail)); + if (widget.app.iconName.endsWith('svg')) { + builder.setLogoSVG(_imagePaths.getConfigurationImagePath(widget.app.iconName)); + } else { + builder.setLogo(_imagePaths.getConfigurationImagePath(widget.app.iconName)); + } + return builder.build(); + } + + Color _backgroundColorItem(BuildContext context) { + if (_isHoverItem) { + return AppColor.colorBgMailboxSelected; + } + return _responsiveUtils.isDesktop(context) + ? AppColor.colorBgDesktop + : Colors.white; + } + + void _openApp(Uri appLink) async { + if (await launcher.canLaunchUrl(appLink)) { + await launcher.launchUrl(appLink); + } + } +} diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index d18d7eca0..a6cd91566 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2022-10-18T14:05:06.644786", + "@@last_modified": "2022-10-19T11:34:56.881127", "initializing_data": "Initializing data...", "@initializing_data": { "type": "text", @@ -2295,5 +2295,11 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "appGridTittle": "Go to applications", + "@appGridTittle": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } \ No newline at end of file diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index f6086fc67..f0c2c4cd5 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -2373,7 +2373,14 @@ class AppLocalizations { String get requestReadReceipt { return Intl.message( 'Request read receipt', - name: 'requestReadReceipt', + name: 'requestReadReceipt' + ); + } + + String get appGridTittle { + return Intl.message( + 'Go to applications', + name: 'appGridTittle' ); } } \ No newline at end of file