TF-381 Add logout action in browser new UI
This commit is contained in:
@@ -2,14 +2,18 @@ import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
typedef OnTapAvatarActionClick = void Function();
|
||||
typedef OnTapAvatarActionWithPositionClick = void Function(RelativeRect? position);
|
||||
|
||||
class AvatarBuilder {
|
||||
|
||||
BuildContext? _context;
|
||||
Key? _key;
|
||||
String? _text;
|
||||
double? _size;
|
||||
Color? _bgColor;
|
||||
Color? _textColor;
|
||||
OnTapAvatarActionClick? _onTapAvatarActionClick;
|
||||
OnTapAvatarActionWithPositionClick? _onTapAvatarActionWithPositionClick;
|
||||
List<Color>? _avatarColors;
|
||||
List<BoxShadow>? _boxShadows;
|
||||
TextStyle? _textStyle;
|
||||
@@ -18,6 +22,10 @@ class AvatarBuilder {
|
||||
_key = key;
|
||||
}
|
||||
|
||||
void context(BuildContext context) {
|
||||
_context = context;
|
||||
}
|
||||
|
||||
void size(double size) {
|
||||
_size = size;
|
||||
}
|
||||
@@ -50,12 +58,26 @@ class AvatarBuilder {
|
||||
_onTapAvatarActionClick = onTapAvatarActionClick;
|
||||
}
|
||||
|
||||
void addOnTapAvatarActionWithPositionClick(OnTapAvatarActionWithPositionClick onTapAvatarActionWithPositionClick) {
|
||||
_onTapAvatarActionWithPositionClick = onTapAvatarActionWithPositionClick;
|
||||
}
|
||||
|
||||
Widget build() {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
if (_onTapAvatarActionClick != null) {
|
||||
_onTapAvatarActionClick!();
|
||||
}},
|
||||
return InkWell(
|
||||
onTap: () => _onTapAvatarActionClick != null ? _onTapAvatarActionClick?.call() : null,
|
||||
onTapDown: (detail) {
|
||||
if (_onTapAvatarActionWithPositionClick != null && _context != null) {
|
||||
final screenSize = MediaQuery.of(_context!).size;
|
||||
final offset = detail.globalPosition;
|
||||
final position = RelativeRect.fromLTRB(
|
||||
offset.dx,
|
||||
offset.dy,
|
||||
screenSize.width - offset.dx,
|
||||
screenSize.height - offset.dy,
|
||||
);
|
||||
_onTapAvatarActionWithPositionClick?.call(position);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
key: _key,
|
||||
width: _size ?? 40,
|
||||
|
||||
@@ -106,6 +106,7 @@ class MailboxController extends BaseMailboxController {
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
mailboxDashBoardController.accountId.listen((accountId) {
|
||||
log('MailboxController::onReady(): accountId: $accountId');
|
||||
if (accountId != null) {
|
||||
getAllMailboxAction(accountId);
|
||||
}
|
||||
@@ -148,6 +149,7 @@ class MailboxController extends BaseMailboxController {
|
||||
super.onData(newState);
|
||||
newState.map((success) async {
|
||||
if (success is GetAllMailboxSuccess) {
|
||||
log('MailboxController::onData(): ${allMailboxes.length}');
|
||||
allMailboxes = success.mailboxList;
|
||||
currentMailboxState = success.currentMailboxState;
|
||||
await buildTree(allMailboxes);
|
||||
|
||||
@@ -14,7 +14,6 @@ import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.da
|
||||
import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/composer_bindings.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/email_controller.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_user_profile_state.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/remove_email_drafts_state.dart';
|
||||
@@ -278,7 +277,6 @@ class MailboxDashBoardController extends ReloadableController {
|
||||
void onClose() {
|
||||
searchInputController.dispose();
|
||||
searchFocus.dispose();
|
||||
Get.delete<EmailController>();
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
import 'package:core/core.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:tmail_ui_user/features/base/base_bindings.dart';
|
||||
import 'package:tmail_ui_user/features/caching/caching_manager.dart';
|
||||
import 'package:tmail_ui_user/features/caching/state_cache_client.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart';
|
||||
@@ -13,6 +15,9 @@ import 'package:tmail_ui_user/features/email/domain/repository/email_repository.
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/move_to_mailbox_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/login/data/repository/credential_repository_impl.dart';
|
||||
import 'package:tmail_ui_user/features/login/domain/repository/credential_repository.dart';
|
||||
import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/data/datasource/state_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/data/datasource_impl/state_datasource_impl.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart';
|
||||
@@ -53,6 +58,8 @@ class ThreadBindings extends BaseBindings {
|
||||
Get.find<LoadMoreEmailsInMailboxInteractor>(),
|
||||
Get.find<SearchEmailInteractor>(),
|
||||
Get.find<SearchMoreEmailInteractor>(),
|
||||
Get.find<DeleteCredentialInteractor>(),
|
||||
Get.find<CachingManager>(),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -90,16 +97,19 @@ class ThreadBindings extends BaseBindings {
|
||||
Get.lazyPut(() => LoadMoreEmailsInMailboxInteractor(Get.find<ThreadRepository>()));
|
||||
Get.lazyPut(() => SearchEmailInteractor(Get.find<ThreadRepository>()));
|
||||
Get.lazyPut(() => SearchMoreEmailInteractor(Get.find<ThreadRepository>()));
|
||||
Get.lazyPut(() => DeleteCredentialInteractor(Get.find<CredentialRepository>()));
|
||||
}
|
||||
|
||||
@override
|
||||
void bindingsRepository() {
|
||||
Get.lazyPut<CredentialRepository>(() => Get.find<CredentialRepositoryImpl>());
|
||||
Get.lazyPut<ThreadRepository>(() => Get.find<ThreadRepositoryImpl>());
|
||||
Get.lazyPut<EmailRepository>(() => Get.find<EmailRepositoryImpl>());
|
||||
}
|
||||
|
||||
@override
|
||||
void bindingsRepositoryImpl() {
|
||||
Get.lazyPut(() => CredentialRepositoryImpl(Get.find<SharedPreferences>()));
|
||||
Get.lazyPut(() => ThreadRepositoryImpl(
|
||||
{
|
||||
DataSourceType.network: Get.find<ThreadDataSource>(),
|
||||
|
||||
@@ -15,6 +15,7 @@ import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/base/base_controller.dart';
|
||||
import 'package:tmail_ui_user/features/caching/caching_manager.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart';
|
||||
@@ -25,6 +26,7 @@ import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_star_sta
|
||||
import 'package:tmail_ui_user/features/email/domain/state/move_to_mailbox_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
|
||||
import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.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/mailbox_dashboard_controller.dart';
|
||||
@@ -69,6 +71,8 @@ class ThreadController extends BaseController {
|
||||
final LoadMoreEmailsInMailboxInteractor _loadMoreEmailsInMailboxInteractor;
|
||||
final SearchEmailInteractor _searchEmailInteractor;
|
||||
final SearchMoreEmailInteractor _searchMoreEmailInteractor;
|
||||
final DeleteCredentialInteractor _deleteCredentialInteractor;
|
||||
final CachingManager _cachingManager;
|
||||
|
||||
final emailList = <PresentationEmail>[].obs;
|
||||
final emailListSearch = <PresentationEmail>[].obs;
|
||||
@@ -102,6 +106,8 @@ class ThreadController extends BaseController {
|
||||
this._loadMoreEmailsInMailboxInteractor,
|
||||
this._searchEmailInteractor,
|
||||
this._searchMoreEmailInteractor,
|
||||
this._deleteCredentialInteractor,
|
||||
this._cachingManager,
|
||||
);
|
||||
|
||||
@override
|
||||
@@ -738,6 +744,30 @@ class ThreadController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
void openUserSettingAction(BuildContext context, RelativeRect? position, List<PopupMenuEntry> popupMenuItems) async {
|
||||
await showMenu(
|
||||
context: context,
|
||||
position: position ?? RelativeRect.fromLTRB(16, 40, 16, 16),
|
||||
color: Colors.white,
|
||||
elevation: 5,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)),
|
||||
items: popupMenuItems);
|
||||
}
|
||||
|
||||
void _deleteCredential() async {
|
||||
await _deleteCredentialInteractor.execute();
|
||||
}
|
||||
|
||||
void _clearAllCache() async {
|
||||
await _cachingManager.clearAll();
|
||||
}
|
||||
|
||||
void logoutAction() {
|
||||
_deleteCredential();
|
||||
_clearAllCache();
|
||||
pushAndPopAll(AppRoutes.LOGIN);
|
||||
}
|
||||
|
||||
void composeEmailAction() {
|
||||
mailboxDashBoardController.composeEmailAction();
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.da
|
||||
import 'package:tmail_ui_user/features/thread/domain/state/search_more_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/extensions/filter_message_option_extension.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/thread_controller.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/app_action_sheet_action_builder.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/app_bar_thread_widget_builder.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/bottom_bar_thread_selection_widget.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_builder.dart';
|
||||
@@ -133,6 +134,12 @@ class ThreadView extends GetWidget<ThreadController> {
|
||||
..text(controller.mailboxDashBoardController.userProfile.value?.getAvatarText() ?? '')
|
||||
..backgroundColor(Colors.white)
|
||||
..textColor(Colors.black)
|
||||
..context(context)
|
||||
..addOnTapAvatarActionWithPositionClick((position) =>
|
||||
controller.openUserSettingAction(
|
||||
context,
|
||||
position,
|
||||
[PopupMenuItem(padding: EdgeInsets.symmetric(horizontal: 8), child: _logoutAction(context))]))
|
||||
..addBoxShadows([BoxShadow(
|
||||
color: AppColor.colorShadowBgContentEmail,
|
||||
spreadRadius: 1, blurRadius: 1, offset: Offset(0, 0.5))])
|
||||
@@ -561,4 +568,14 @@ class ThreadView extends GetWidget<ThreadController> {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Widget _logoutAction(BuildContext context) {
|
||||
return (AppActionSheetActionBuilder(
|
||||
Key('logout_action'),
|
||||
SvgPicture.asset(_imagePaths.icCloseMailbox, color: AppColor.colorTextButton, fit: BoxFit.fill),
|
||||
AppLocalizations.of(context).logout,
|
||||
iconLeftPadding:EdgeInsets.only(right: 12))
|
||||
..onActionClick((option) => controller.logoutAction()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
|
||||
class AppActionSheetActionBuilder extends CupertinoActionSheetActionBuilder {
|
||||
|
||||
final Color? bgColor;
|
||||
final EdgeInsets? iconLeftPadding;
|
||||
|
||||
AppActionSheetActionBuilder(
|
||||
Key key,
|
||||
SvgPicture actionIcon,
|
||||
String actionName,
|
||||
{
|
||||
this.bgColor,
|
||||
this.iconLeftPadding,
|
||||
}
|
||||
) : super(key, actionIcon, actionName);
|
||||
|
||||
@override
|
||||
Widget build() {
|
||||
return Container(
|
||||
color: bgColor ?? Colors.white,
|
||||
child: CupertinoActionSheetAction(
|
||||
key: key,
|
||||
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
Padding(
|
||||
padding: iconLeftPadding ?? EdgeInsets.only(left: 12, right: 16),
|
||||
child: actionIcon),
|
||||
Expanded(child: Text(actionName, textAlign: TextAlign.left, style: actionTextStyle())),
|
||||
]),
|
||||
onPressed: () => onCupertinoActionSheetActionClick?.call(null),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user