TF-987: Email range selection (Shift)

This commit is contained in:
ManhNTX
2022-11-03 15:32:26 +07:00
committed by Dat H. Pham
parent 769069f125
commit e4cf4808cb
5 changed files with 65 additions and 13 deletions
@@ -55,8 +55,8 @@ class TopBarThreadSelection {
buildIconWeb( buildIconWeb(
icon: SvgPicture.asset( icon: SvgPicture.asset(
listEmail.isAllEmailRead listEmail.isAllEmailRead
? imagePaths.icRead ? imagePaths.icUnread
: imagePaths.icUnread, : imagePaths.icRead,
fit: BoxFit.fill), fit: BoxFit.fill),
tooltip: listEmail.isAllEmailRead tooltip: listEmail.isAllEmailRead
? AppLocalizations.of(context).mark_as_unread ? AppLocalizations.of(context).mark_as_unread
@@ -60,8 +60,8 @@ class AppBarSelectionMode extends StatelessWidget {
splashRadius: 15, splashRadius: 15,
icon: SvgPicture.asset( icon: SvgPicture.asset(
listEmail.isAllEmailRead listEmail.isAllEmailRead
? _imagePaths.icRead ? _imagePaths.icUnread
: _imagePaths.icUnread, : _imagePaths.icRead,
fit: BoxFit.fill), fit: BoxFit.fill),
tooltip: listEmail.isAllEmailRead tooltip: listEmail.isAllEmailRead
? AppLocalizations.of(context).unread ? AppLocalizations.of(context).unread
@@ -1,6 +1,7 @@
import 'package:core/core.dart'; import 'package:core/core.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.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/account_id.dart';
@@ -100,7 +101,7 @@ class ThreadController extends BaseController {
final CachingManager _cachingManager; final CachingManager _cachingManager;
final listEmailDrag = <PresentationEmail>[].obs; final listEmailDrag = <PresentationEmail>[].obs;
bool shiftSelectedMode = false;
bool canLoadMore = true; bool canLoadMore = true;
bool canSearchMore = true; bool canSearchMore = true;
bool _isLoadingMore = false; bool _isLoadingMore = false;
@@ -108,6 +109,8 @@ class ThreadController extends BaseController {
MailboxId? _currentMailboxId; MailboxId? _currentMailboxId;
jmap.State? _currentEmailState; jmap.State? _currentEmailState;
final ScrollController listEmailController = ScrollController(); final ScrollController listEmailController = ScrollController();
final FocusNode focusNodeKeyBoard = FocusNode();
final latestEmailAction = Rxn<PresentationEmail>();
late Worker mailboxWorker, searchWorker, dashboardActionWorker, viewStateWorker, advancedSearchFilterWorker; late Worker mailboxWorker, searchWorker, dashboardActionWorker, viewStateWorker, advancedSearchFilterWorker;
Set<Comparator>? get _sortOrder => <Comparator>{} Set<Comparator>? get _sortOrder => <Comparator>{}
@@ -160,6 +163,7 @@ class ThreadController extends BaseController {
@override @override
void onClose() { void onClose() {
listEmailController.dispose(); listEmailController.dispose();
focusNodeKeyBoard.dispose();
_clearWorker(); _clearWorker();
super.onClose(); super.onClose();
} }
@@ -516,11 +520,45 @@ class ThreadController extends BaseController {
mailboxDashBoardController.dispatchRoute(DashboardRoutes.emailDetailed); mailboxDashBoardController.dispatchRoute(DashboardRoutes.emailDetailed);
} }
void selectEmail(BuildContext context, PresentationEmail presentationEmailSelected) { void _shiftSelectEmail(PresentationEmail presentationEmailSelected) {
emailList.value = emailList int startIndexAction = 0;
.map((email) => email.id == presentationEmailSelected.id ? email.toggleSelect() : email) int endIndexAction = 0;
.toList(); final indexOfPresentationEmailSelected = emailList.indexWhere((e) => e.id == presentationEmailSelected.id);
final indexOfLatestEmailAction = emailList.indexWhere((e) => e.id == latestEmailAction.value?.id);
if (indexOfPresentationEmailSelected > indexOfLatestEmailAction) {
startIndexAction = indexOfLatestEmailAction;
endIndexAction = indexOfPresentationEmailSelected;
} else {
startIndexAction = indexOfPresentationEmailSelected;
endIndexAction = indexOfLatestEmailAction;
}
final enableChangeSelectModeOfEmailsToActive = latestEmailAction.value?.selectMode == SelectMode.ACTIVE &&
!emailList.sublist(startIndexAction, endIndexAction).every((e) => e.selectMode == SelectMode.ACTIVE) ||
latestEmailAction.value?.selectMode == SelectMode.INACTIVE &&
emailList.sublist(startIndexAction, endIndexAction).every((e) => e.selectMode == SelectMode.INACTIVE);
if (enableChangeSelectModeOfEmailsToActive) {
emailList.value = emailList.asMap().map((index, email) {
return MapEntry(index, index >= startIndexAction && index <= endIndexAction ? email.toSelectedEmail(selectMode: SelectMode.ACTIVE) : email);
}).values.toList();
} else {
emailList.value = emailList.asMap().map((index, email) {
return MapEntry(index, index >= startIndexAction && index <= endIndexAction ? email.toSelectedEmail(selectMode: SelectMode.INACTIVE) : email);
}).values.toList();
}
}
void selectEmail(BuildContext context, PresentationEmail presentationEmailSelected) {
if (shiftSelectedMode && latestEmailAction.value != null && latestEmailAction.value?.id != presentationEmailSelected.id) {
_shiftSelectEmail(presentationEmailSelected);
} else {
emailList.value = emailList
.map((email) => email.id == presentationEmailSelected.id ? email.toggleSelect() : email)
.toList();
}
latestEmailAction.value = emailList.firstWhere((e) => e.id == presentationEmailSelected.id);
focusNodeKeyBoard.requestFocus();
if (_isUnSelectedAll()) { if (_isUnSelectedAll()) {
mailboxDashBoardController.currentSelectMode.value = SelectMode.INACTIVE; mailboxDashBoardController.currentSelectMode.value = SelectMode.INACTIVE;
mailboxDashBoardController.listEmailSelected.clear(); mailboxDashBoardController.listEmailSelected.clear();
@@ -1470,4 +1508,18 @@ class ThreadController extends BaseController {
} }
} }
} }
KeyEventResult handleKeyEvent(FocusNode node, RawKeyEvent event) {
final shiftEvent = event.logicalKey == LogicalKeyboardKey.shiftLeft || event.logicalKey == LogicalKeyboardKey.shiftRight;
if (event is RawKeyDownEvent && shiftEvent) {
shiftSelectedMode = true;
}
if (event is RawKeyUpEvent && shiftEvent) {
shiftSelectedMode = false;
}
return shiftEvent
? KeyEventResult.handled
: KeyEventResult.ignored;
}
} }
@@ -112,8 +112,8 @@ class AppBarThreadWidgetBuilder extends StatelessWidget {
splashRadius: 15, splashRadius: 15,
icon: SvgPicture.asset( icon: SvgPicture.asset(
_listSelectionEmail.isAllEmailRead _listSelectionEmail.isAllEmailRead
? _imagePaths.icRead ? _imagePaths.icUnread
: _imagePaths.icUnread, : _imagePaths.icRead,
fit: BoxFit.fill), fit: BoxFit.fill),
tooltip: _listSelectionEmail.isAllEmailRead tooltip: _listSelectionEmail.isAllEmailRead
? AppLocalizations.of(context).unread ? AppLocalizations.of(context).unread
@@ -393,8 +393,8 @@ class EmailTileBuilder with BaseEmailItemTile {
splashRadius: 10, splashRadius: 10,
icon: SvgPicture.asset( icon: SvgPicture.asset(
_presentationEmail.hasRead _presentationEmail.hasRead
? imagePaths.icRead ? imagePaths.icUnread
: imagePaths.icUnread, : imagePaths.icRead,
color: AppColor.colorActionButtonHover, color: AppColor.colorActionButtonHover,
width: 16, width: 16,
height: 16, height: 16,