TF-4227 Fix conflict with master branch
This commit is contained in:
@@ -176,6 +176,8 @@ PODS:
|
||||
- nanopb/encode (= 2.30909.1)
|
||||
- nanopb/decode (2.30909.1)
|
||||
- nanopb/encode (2.30909.1)
|
||||
- objective_c (0.0.1):
|
||||
- Flutter
|
||||
- open_file_ios (0.0.1):
|
||||
- Flutter
|
||||
- OrderedSet (6.0.3)
|
||||
@@ -210,11 +212,18 @@ PODS:
|
||||
- SDWebImageWebPCoder (0.14.6):
|
||||
- libwebp (~> 1.0)
|
||||
- SDWebImage/Core (~> 5.17)
|
||||
- Sentry/HybridSDK (8.56.2)
|
||||
- sentry_flutter (9.8.0):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- Sentry/HybridSDK (= 8.56.2)
|
||||
- share_plus (0.0.1):
|
||||
- Flutter
|
||||
- shared_preferences_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- super_dns_client (0.0.1):
|
||||
- Flutter
|
||||
- SwiftyGif (5.4.5)
|
||||
- UniversalDetector2 (2.0.1)
|
||||
- url_launcher_ios (0.0.1):
|
||||
@@ -247,6 +256,7 @@ DEPENDENCIES:
|
||||
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
|
||||
- flutter_web_auth_2 (from `.symlinks/plugins/flutter_web_auth_2/ios`)
|
||||
- lottie_native (from `.symlinks/plugins/lottie_native/ios`)
|
||||
- objective_c (from `.symlinks/plugins/objective_c/ios`)
|
||||
- open_file_ios (from `.symlinks/plugins/open_file_ios/ios`)
|
||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||
@@ -257,8 +267,10 @@ DEPENDENCIES:
|
||||
- pointer_interceptor_ios (from `.symlinks/plugins/pointer_interceptor_ios/ios`)
|
||||
- printing (from `.symlinks/plugins/printing/ios`)
|
||||
- receive_sharing_intent (from `.symlinks/plugins/receive_sharing_intent/ios`)
|
||||
- sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`)
|
||||
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||
- super_dns_client (from `.symlinks/plugins/super_dns_client/ios`)
|
||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||
- workmanager_apple (from `.symlinks/plugins/workmanager_apple/ios`)
|
||||
|
||||
@@ -284,6 +296,7 @@ SPEC REPOS:
|
||||
- ReachabilitySwift
|
||||
- SDWebImage
|
||||
- SDWebImageWebPCoder
|
||||
- Sentry
|
||||
- SwiftyGif
|
||||
- UniversalDetector2
|
||||
|
||||
@@ -336,6 +349,8 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/flutter_web_auth_2/ios"
|
||||
lottie_native:
|
||||
:path: ".symlinks/plugins/lottie_native/ios"
|
||||
objective_c:
|
||||
:path: ".symlinks/plugins/objective_c/ios"
|
||||
open_file_ios:
|
||||
:path: ".symlinks/plugins/open_file_ios/ios"
|
||||
package_info_plus:
|
||||
@@ -356,10 +371,14 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/printing/ios"
|
||||
receive_sharing_intent:
|
||||
:path: ".symlinks/plugins/receive_sharing_intent/ios"
|
||||
sentry_flutter:
|
||||
:path: ".symlinks/plugins/sentry_flutter/ios"
|
||||
share_plus:
|
||||
:path: ".symlinks/plugins/share_plus/ios"
|
||||
shared_preferences_foundation:
|
||||
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
||||
super_dns_client:
|
||||
:path: ".symlinks/plugins/super_dns_client/ios"
|
||||
url_launcher_ios:
|
||||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||
workmanager_apple:
|
||||
@@ -405,6 +424,7 @@ SPEC CHECKSUMS:
|
||||
lottie_native: c2e590a297861fc32a0188cf8dab39aa97f86d81
|
||||
Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d
|
||||
nanopb: d4d75c12cd1316f4a64e3c6963f879ecd4b5e0d5
|
||||
objective_c: 89e720c30d716b036faf9c9684022048eee1eee2
|
||||
open_file_ios: 5ff7526df64e4394b4fe207636b67a95e83078bb
|
||||
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
|
||||
package_info_plus: 580e9a5f1b6ca5594e7c9ed5f92d1dfb2a66b5e1
|
||||
@@ -420,8 +440,11 @@ SPEC CHECKSUMS:
|
||||
receive_sharing_intent: 222384f00ffe7e952bbfabaa9e3967cb87e5fe00
|
||||
SDWebImage: f29024626962457f3470184232766516dee8dfea
|
||||
SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
|
||||
Sentry: b53951377b78e21a734f5dc8318e333dbfc682d7
|
||||
sentry_flutter: 4c33648b7e83310aa1fdb1b10c5491027d9643f0
|
||||
share_plus: de6030e33b4e106470e09322d87cf2a4258d2d1d
|
||||
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
||||
super_dns_client: 03e8ebf4df47d1335d1027299f8d2365b7a7bb59
|
||||
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
||||
UniversalDetector2: 7c9ffd935cf050eeb19edf7e90f6febe3743a1af
|
||||
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
|
||||
|
||||
+59
-3
@@ -268,10 +268,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: dio
|
||||
sha256: "9fdbf71baeb250fc9da847f6cb2052196f62c19906a3657adfc18631a667d316"
|
||||
sha256: e44ce32c01f02c54a101551def8586f15d6189b4f999d4420aad38995ac62e6d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
version: "5.2.0"
|
||||
equatable:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -381,6 +381,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
flutter_dotenv:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_dotenv
|
||||
sha256: d9283d92059a22e9834bc0a31336658ffba77089fb6f3cc36751f1fc7c6661a3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.2"
|
||||
flutter_hsvcolor_picker:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -684,10 +692,18 @@ packages:
|
||||
description:
|
||||
path: "."
|
||||
ref: main
|
||||
resolved-ref: "446efbbccdde981371b4d2a636762184adf6e926"
|
||||
resolved-ref: "8e2bd9cb1bbd8236be895aa04bf0d0da8e2ff3b2"
|
||||
url: "https://github.com/linagora/jmap-dart-client.git"
|
||||
source: git
|
||||
version: "0.3.6"
|
||||
jni:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: jni
|
||||
sha256: d2c361082d554d4593c3012e26f6b188f902acd291330f13d6427641a92b3da1
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.14.2"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -792,6 +808,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.6"
|
||||
objective_c:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: objective_c
|
||||
sha256: "64e35e1e2e79da4e83f2ace3bf4e5437cef523f46c7db2eba9a1419c49573790"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.0.0"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1025,6 +1049,30 @@ packages:
|
||||
url: "https://github.com/linagora/dart-neats.git"
|
||||
source: git
|
||||
version: "2.1.0"
|
||||
sentry:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sentry
|
||||
sha256: "10a0bc25f5f21468e3beeae44e561825aaa02cdc6829438e73b9b64658ff88d9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.8.0"
|
||||
sentry_dio:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sentry_dio
|
||||
sha256: bee438fd790c534da77f0a6c9cd04c54c818184b8a54bbe7d916489c8aad56a0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.8.0"
|
||||
sentry_flutter:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sentry_flutter
|
||||
sha256: aafbf41c63c98a30b17bdbf3313424d5102db62b08735c44bff810f277e786a5
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.8.0"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1222,6 +1270,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.5"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: uuid
|
||||
sha256: a11b666489b1954e01d992f3d601b1804a33937b5a8fe677bd26b8a9f96f96e8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.5.2"
|
||||
vector_graphics:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ dependencies:
|
||||
|
||||
json_annotation: 4.8.0
|
||||
|
||||
dio: 5.0.0
|
||||
dio: 5.2.0
|
||||
|
||||
quiver: 3.2.1
|
||||
|
||||
|
||||
@@ -205,7 +205,7 @@ void main() {
|
||||
(builder..usings(method.requiredCapabilities)).build().execute();
|
||||
|
||||
// Assert
|
||||
expect(call, throwsA(isA<DioError>()));
|
||||
expect(call, throwsA(isA<DioException>()));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ void main() {
|
||||
(builder..usings(method.requiredCapabilities)).build().execute();
|
||||
|
||||
// Assert
|
||||
expect(future, throwsA(isA<DioError>()));
|
||||
expect(future, throwsA(isA<DioException>()));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ void main() {
|
||||
(builder..usings(method.requiredCapabilities)).build().execute();
|
||||
|
||||
// Assert
|
||||
expect(call, throwsA(isA<DioError>()));
|
||||
expect(call, throwsA(isA<DioException>()));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -54,13 +54,4 @@ class TagWidget extends StatelessWidget {
|
||||
child: labelText,
|
||||
);
|
||||
}
|
||||
|
||||
String _truncateName(String name, {int maxLength = 16}) {
|
||||
try {
|
||||
if (name.length <= maxLength) return name;
|
||||
return '${name.substring(0, maxLength - 1)}...';
|
||||
} catch (_) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,21 +150,14 @@ extension PresentationMailboxExtension on PresentationMailbox {
|
||||
String? get filterKeyword {
|
||||
if (isFavorite) {
|
||||
return KeyWordIdentifier.emailFlagged.value;
|
||||
} else if (isLabelMailbox) {
|
||||
return (this as PresentationLabelMailbox).label.keyword?.value;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
bool get isCacheable => !isFavorite && this is! PresentationLabelMailbox;
|
||||
bool get isCacheable => !isVirtualFolder && this is! PresentationLabelMailbox;
|
||||
|
||||
bool get isLabelMailbox => this is PresentationLabelMailbox;
|
||||
|
||||
String? get filterKeyword {
|
||||
if (isFavorite) {
|
||||
return KeyWordIdentifier.emailFlagged.value;
|
||||
}
|
||||
if (isLabelMailbox) {
|
||||
return (this as PresentationLabelMailbox).label.keyword?.value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -52,11 +52,11 @@ class PreferencesController extends BaseController {
|
||||
final accountDashboardController = Get.find<ManageAccountDashBoardController>();
|
||||
|
||||
bool get isAICapabilitySupported {
|
||||
return _manageAccountDashBoardController.isAICapabilitySupported;
|
||||
return accountDashboardController.isAICapabilitySupported;
|
||||
}
|
||||
|
||||
bool get isAIScribeCapabilityAvailable {
|
||||
return _manageAccountDashBoardController.isAIScribeCapabilityAvailable;
|
||||
return accountDashboardController.isAIScribeCapabilityAvailable;
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -2,8 +2,6 @@ import 'package:jmap_dart_client/jmap/core/filter/filter.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/filter/filter_operator.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/filter/operator/logic_filter_operator.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/utc_date.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/filter/filter_operator.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/filter/operator/logic_filter_operator.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_filter_condition.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||
@@ -26,10 +24,20 @@ class MailboxFilterBuilder {
|
||||
|
||||
MailboxId? get _mailboxId => selectedMailbox?.id;
|
||||
|
||||
bool get _isVirtualFolder => selectedMailbox?.isVirtualFolder == true;
|
||||
|
||||
bool get _isActionRequired => selectedMailbox?.isActionRequired == true;
|
||||
|
||||
bool get _isFavorite => selectedMailbox?.isFavorite == true;
|
||||
|
||||
bool get _isLabelMailbox => selectedMailbox?.isLabelMailbox == true;
|
||||
|
||||
String? get _filterKeyword => selectedMailbox?.filterKeyword;
|
||||
|
||||
EmailFilter buildEmailFilterForLoadMailbox() {
|
||||
final filterCondition = buildFilterCondition();
|
||||
|
||||
if (selectedMailbox?.isVirtualFolder == true) {
|
||||
if (_isVirtualFolder) {
|
||||
return EmailFilter(filter: filterCondition);
|
||||
}
|
||||
|
||||
@@ -43,48 +51,17 @@ class MailboxFilterBuilder {
|
||||
Filter buildFilterCondition({PresentationEmail? oldestEmail}) {
|
||||
final before = oldestEmail?.receivedAt;
|
||||
|
||||
if (selectedMailbox?.isFavorite == true) {
|
||||
return _buildFavoriteMailboxFilter(before: before);
|
||||
}
|
||||
|
||||
if (selectedMailbox?.isActionRequired == true) {
|
||||
if (_isActionRequired) {
|
||||
return _buildActionRequiredMailboxFilter(before: before);
|
||||
}
|
||||
|
||||
if (selectedMailbox?.isLabelMailbox == true) {
|
||||
return _buildKeywordBasedFilter(
|
||||
selectedMailbox?.filterKeyword,
|
||||
before: before,
|
||||
);
|
||||
if (_isFavorite || _isLabelMailbox) {
|
||||
return _buildKeywordBasedFilter(keyword: _filterKeyword, before: before);
|
||||
}
|
||||
|
||||
return buildDefaultMailboxFilter(before: before);
|
||||
}
|
||||
|
||||
Filter _buildFavoriteMailboxFilter({UTCDate? before}) {
|
||||
switch (filterMessageOption) {
|
||||
case FilterMessageOption.unread:
|
||||
return EmailFilterCondition(
|
||||
notKeyword: KeyWordIdentifier.emailSeen.value,
|
||||
hasKeyword: KeyWordIdentifier.emailFlagged.value,
|
||||
before: before,
|
||||
);
|
||||
|
||||
case FilterMessageOption.attachments:
|
||||
return EmailFilterCondition(
|
||||
hasAttachment: true,
|
||||
hasKeyword: KeyWordIdentifier.emailFlagged.value,
|
||||
before: before,
|
||||
);
|
||||
|
||||
default:
|
||||
return EmailFilterCondition(
|
||||
hasKeyword: KeyWordIdentifier.emailFlagged.value,
|
||||
before: before,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Filter _buildActionRequiredMailboxFilter({UTCDate? before}) {
|
||||
switch (filterMessageOption) {
|
||||
case FilterMessageOption.starred:
|
||||
@@ -98,7 +75,6 @@ class MailboxFilterBuilder {
|
||||
EmailFilterCondition(
|
||||
notKeyword: KeyWordIdentifier.emailSeen.value,
|
||||
hasKeyword: KeyWordIdentifierExtension.needsActionMail.value,
|
||||
before: before,
|
||||
),
|
||||
},
|
||||
);
|
||||
@@ -121,7 +97,7 @@ class MailboxFilterBuilder {
|
||||
}
|
||||
|
||||
Filter _buildKeywordBasedFilter({
|
||||
required String keyword,
|
||||
required String? keyword,
|
||||
UTCDate? before,
|
||||
}) {
|
||||
switch (filterMessageOption) {
|
||||
@@ -146,18 +122,12 @@ class MailboxFilterBuilder {
|
||||
EmailFilterCondition(
|
||||
hasKeyword: KeyWordIdentifier.emailFlagged.value,
|
||||
),
|
||||
EmailFilterCondition(
|
||||
hasKeyword: keyword,
|
||||
before: oldestEmail?.receivedAt,
|
||||
),
|
||||
EmailFilterCondition(hasKeyword: keyword, before: before),
|
||||
},
|
||||
);
|
||||
|
||||
default:
|
||||
return EmailFilterCondition(
|
||||
hasKeyword: keyword,
|
||||
before: before,
|
||||
);
|
||||
return EmailFilterCondition(hasKeyword: keyword, before: before);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +138,6 @@ class MailboxFilterBuilder {
|
||||
|
||||
case FilterMessageOption.unread:
|
||||
return EmailFilterCondition(
|
||||
inMailbox: mailboxId,
|
||||
notKeyword: KeyWordIdentifier.emailSeen.value,
|
||||
before: before,
|
||||
inMailbox: _mailboxId,
|
||||
@@ -176,7 +145,6 @@ class MailboxFilterBuilder {
|
||||
|
||||
case FilterMessageOption.attachments:
|
||||
return EmailFilterCondition(
|
||||
inMailbox: mailboxId,
|
||||
hasAttachment: true,
|
||||
before: before,
|
||||
inMailbox: _mailboxId,
|
||||
@@ -184,7 +152,6 @@ class MailboxFilterBuilder {
|
||||
|
||||
case FilterMessageOption.starred:
|
||||
return EmailFilterCondition(
|
||||
inMailbox: mailboxId,
|
||||
hasKeyword: KeyWordIdentifier.emailFlagged.value,
|
||||
before: before,
|
||||
inMailbox: _mailboxId,
|
||||
|
||||
@@ -64,7 +64,6 @@ import 'package:tmail_ui_user/features/thread/presentation/extensions/handle_ema
|
||||
import 'package:tmail_ui_user/features/thread/presentation/extensions/handle_keyboard_shortcut_actions_extension.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/extensions/list_presentation_email_extensions.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/extensions/refresh_thread_detail_extension.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/filters/mailbox_filter_builder.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/mixin/email_action_controller.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/model/delete_action_type.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/model/loading_more_status.dart';
|
||||
@@ -822,13 +821,13 @@ class ThreadController extends BaseController with EmailActionController {
|
||||
}
|
||||
|
||||
void _loadMoreEmailsSuccess(LoadMoreEmailsSuccess success) {
|
||||
canLoadMore = success.emailList.isNotEmpty;
|
||||
loadingMoreStatus.value = LoadingMoreStatus.completed;
|
||||
final appendableList = validateListEmailsLoadMore(success.emailList);
|
||||
log('ThreadController::_loadMoreEmailsSuccess: emailList = ${success.emailList.length} | appendableList = ${appendableList.length}');
|
||||
if (appendableList.isNotEmpty) {
|
||||
mailboxDashBoardController.emailsInCurrentMailbox.addAll(appendableList);
|
||||
}
|
||||
canLoadMore = success.emailList.isNotEmpty && appendableList.isNotEmpty;
|
||||
if (PlatformInfo.isWeb) {
|
||||
_validateBrowserHeight();
|
||||
}
|
||||
|
||||
@@ -618,6 +618,23 @@ class ThreadView extends GetWidget<ThreadController>
|
||||
|
||||
final isAINeedsActionEnabled = dashboardController.isAINeedsActionEnabled;
|
||||
|
||||
final isLabelCapabilitySupported =
|
||||
dashboardController.isLabelCapabilitySupported;
|
||||
|
||||
final labelController =
|
||||
controller.mailboxDashBoardController.labelController;
|
||||
|
||||
final isLabelSettingEnabled =
|
||||
labelController.isLabelSettingEnabled.isTrue;
|
||||
|
||||
List<Label>? emailLabels;
|
||||
|
||||
if (isLabelCapabilitySupported && isLabelSettingEnabled) {
|
||||
emailLabels = presentationEmail.getLabelList(
|
||||
labelController.labels,
|
||||
);
|
||||
}
|
||||
|
||||
return Dismissible(
|
||||
key: ValueKey<EmailId?>(presentationEmail.id),
|
||||
direction: controller.getSwipeDirection(
|
||||
@@ -631,40 +648,21 @@ class ThreadView extends GetWidget<ThreadController>
|
||||
presentationEmail,
|
||||
direction,
|
||||
),
|
||||
child: Obx(() {
|
||||
final isLabelCapabilitySupported = controller
|
||||
.mailboxDashBoardController.isLabelCapabilitySupported;
|
||||
|
||||
final labelController =
|
||||
controller.mailboxDashBoardController.labelController;
|
||||
|
||||
final isLabelSettingEnabled =
|
||||
labelController.isLabelSettingEnabled.isTrue;
|
||||
|
||||
List<Label>? emailLabels;
|
||||
|
||||
if (isLabelCapabilitySupported && isLabelSettingEnabled) {
|
||||
emailLabels = presentationEmail.getLabelList(
|
||||
labelController.labels,
|
||||
);
|
||||
}
|
||||
|
||||
return EmailTileBuilder(
|
||||
key: Key('email_tile_builder_${presentationEmail.id?.asString}'),
|
||||
presentationEmail: presentationEmail,
|
||||
selectAllMode: selectModeAll,
|
||||
isShowingEmailContent: isShowingEmailContent,
|
||||
isSenderImportantFlagEnabled: isSenderImportantFlagEnabled,
|
||||
searchQuery: controller.searchQuery,
|
||||
mailboxContain: presentationEmail.mailboxContain,
|
||||
isSearchEmailRunning: controller.searchController.isSearchEmailRunning,
|
||||
isAINeedsActionEnabled: isAINeedsActionEnabled,
|
||||
labels: emailLabels,
|
||||
emailActionClick: _handleEmailActionClicked,
|
||||
onMoreActionClick: (email, position) =>
|
||||
_handleEmailContextMenuAction(context, email, position),
|
||||
);
|
||||
}),
|
||||
child: EmailTileBuilder(
|
||||
key: Key('email_tile_builder_${presentationEmail.id?.asString}'),
|
||||
presentationEmail: presentationEmail,
|
||||
selectAllMode: selectModeAll,
|
||||
isShowingEmailContent: isShowingEmailContent,
|
||||
isSenderImportantFlagEnabled: isSenderImportantFlagEnabled,
|
||||
searchQuery: controller.searchQuery,
|
||||
mailboxContain: presentationEmail.mailboxContain,
|
||||
isSearchEmailRunning: isSearchEmailRunning,
|
||||
isAINeedsActionEnabled: isAINeedsActionEnabled,
|
||||
labels: emailLabels,
|
||||
emailActionClick: _handleEmailActionClicked,
|
||||
onMoreActionClick: (email, position) =>
|
||||
_handleEmailContextMenuAction(context, email, position),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,9 +7,11 @@ import 'package:jmap_dart_client/jmap/core/utc_date.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_filter_condition.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||
import 'package:labels/model/label.dart';
|
||||
import 'package:model/email/presentation_email.dart';
|
||||
import 'package:model/extensions/keyword_identifier_extension.dart';
|
||||
import 'package:model/mailbox/presentation_mailbox.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/presentation_label_mailbox.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/model/filter_message_option.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/filters/mailbox_filter_builder.dart';
|
||||
|
||||
@@ -99,17 +101,23 @@ void main() {
|
||||
);
|
||||
|
||||
test(
|
||||
'Starred filter → flagged only',
|
||||
'Starred filter → flagged only (deduplicated by Set)',
|
||||
() {
|
||||
final builder = MailboxFilterBuilder(
|
||||
selectedMailbox: mailbox(favorite: true),
|
||||
filterMessageOption: FilterMessageOption.starred,
|
||||
);
|
||||
|
||||
final filter = builder.buildFilterCondition() as EmailFilterCondition;
|
||||
final filter = builder.buildFilterCondition();
|
||||
expect(filter, isA<LogicFilterOperator>());
|
||||
|
||||
expect(filter.hasKeyword, KeyWordIdentifier.emailFlagged.value);
|
||||
expect(filter.notKeyword, isNull);
|
||||
final logic = filter as LogicFilterOperator;
|
||||
expect(logic.operator, Operator.AND);
|
||||
|
||||
expect(logic.conditions.length, 1);
|
||||
|
||||
final condition = logic.conditions.first as EmailFilterCondition;
|
||||
expect(condition.hasKeyword, KeyWordIdentifier.emailFlagged.value);
|
||||
},
|
||||
);
|
||||
});
|
||||
@@ -318,7 +326,7 @@ void main() {
|
||||
);
|
||||
|
||||
test(
|
||||
'Before date propagated into all conditions of LogicFilterOperator',
|
||||
'Before date propagated into at least one condition of LogicFilterOperator',
|
||||
() {
|
||||
final before = beforeDate();
|
||||
|
||||
@@ -331,10 +339,13 @@ void main() {
|
||||
oldestEmail: PresentationEmail(receivedAt: before),
|
||||
) as LogicFilterOperator;
|
||||
|
||||
for (final condition in filter.conditions) {
|
||||
final emailFilter = condition as EmailFilterCondition;
|
||||
expect(emailFilter.before, before);
|
||||
}
|
||||
final conditions = filter.conditions.cast<EmailFilterCondition>();
|
||||
|
||||
expect(
|
||||
conditions.any((c) => c.before == before),
|
||||
true,
|
||||
reason: 'At least one condition must contain before date',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -440,4 +451,170 @@ void main() {
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
group('Label mailbox - buildFilterCondition', () {
|
||||
PresentationMailbox labelMailbox(KeyWordIdentifier keyword) {
|
||||
final label = Label(
|
||||
id: Id('label-1'),
|
||||
keyword: keyword,
|
||||
displayName: keyword.value,
|
||||
);
|
||||
return PresentationLabelMailbox.initial(label);
|
||||
}
|
||||
|
||||
test(
|
||||
'Label + All filter → has label keyword',
|
||||
() {
|
||||
final builder = MailboxFilterBuilder(
|
||||
selectedMailbox: labelMailbox(KeyWordIdentifier.emailFlagged),
|
||||
filterMessageOption: FilterMessageOption.all,
|
||||
);
|
||||
|
||||
final filter = builder.buildFilterCondition() as EmailFilterCondition;
|
||||
|
||||
expect(filter.hasKeyword, KeyWordIdentifier.emailFlagged.value);
|
||||
expect(filter.notKeyword, isNull);
|
||||
expect(filter.hasAttachment, isNull);
|
||||
expect(filter.inMailbox, isNull);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'Label + Unread → not seen AND label keyword',
|
||||
() {
|
||||
final builder = MailboxFilterBuilder(
|
||||
selectedMailbox: labelMailbox(KeyWordIdentifier.emailFlagged),
|
||||
filterMessageOption: FilterMessageOption.unread,
|
||||
);
|
||||
|
||||
final filter = builder.buildFilterCondition() as EmailFilterCondition;
|
||||
|
||||
expect(filter.notKeyword, KeyWordIdentifier.emailSeen.value);
|
||||
expect(filter.hasKeyword, KeyWordIdentifier.emailFlagged.value);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'Label + Attachments → hasAttachment AND label keyword',
|
||||
() {
|
||||
final builder = MailboxFilterBuilder(
|
||||
selectedMailbox: labelMailbox(KeyWordIdentifier.emailFlagged),
|
||||
filterMessageOption: FilterMessageOption.attachments,
|
||||
);
|
||||
|
||||
final filter = builder.buildFilterCondition() as EmailFilterCondition;
|
||||
|
||||
expect(filter.hasAttachment, true);
|
||||
expect(filter.hasKeyword, KeyWordIdentifier.emailFlagged.value);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'Label + Starred → AND(flagged, label keyword) with dedup',
|
||||
() {
|
||||
final builder = MailboxFilterBuilder(
|
||||
selectedMailbox: labelMailbox(KeyWordIdentifier.emailFlagged),
|
||||
filterMessageOption: FilterMessageOption.starred,
|
||||
);
|
||||
|
||||
final filter = builder.buildFilterCondition();
|
||||
expect(filter, isA<LogicFilterOperator>());
|
||||
|
||||
final logic = filter as LogicFilterOperator;
|
||||
|
||||
expect(logic.conditions.length, 1);
|
||||
final c = logic.conditions.first as EmailFilterCondition;
|
||||
expect(c.hasKeyword, KeyWordIdentifier.emailFlagged.value);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'Label mailbox propagates before date',
|
||||
() {
|
||||
final before = beforeDate();
|
||||
|
||||
final builder = MailboxFilterBuilder(
|
||||
selectedMailbox: labelMailbox(KeyWordIdentifier.emailFlagged),
|
||||
filterMessageOption: FilterMessageOption.unread,
|
||||
);
|
||||
|
||||
final filter = builder.buildFilterCondition(
|
||||
oldestEmail: PresentationEmail(receivedAt: before),
|
||||
) as EmailFilterCondition;
|
||||
|
||||
expect(filter.before, before);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
group('Edge - Label mailbox with null keyword', () {
|
||||
PresentationMailbox labelMailboxWithNullKeyword() {
|
||||
final label = Label(
|
||||
id: Id('label-null'),
|
||||
keyword: null,
|
||||
displayName: 'NoKeyword',
|
||||
);
|
||||
return PresentationLabelMailbox.initial(label);
|
||||
}
|
||||
|
||||
test(
|
||||
'Label with null keyword → filter has no hasKeyword',
|
||||
() {
|
||||
final builder = MailboxFilterBuilder(
|
||||
selectedMailbox: labelMailboxWithNullKeyword(),
|
||||
filterMessageOption: FilterMessageOption.all,
|
||||
);
|
||||
|
||||
final filter = builder.buildFilterCondition() as EmailFilterCondition;
|
||||
|
||||
expect(filter.hasKeyword, isNull);
|
||||
expect(filter.notKeyword, isNull);
|
||||
expect(filter.hasAttachment, isNull);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
group('Edge - ActionRequired + Attachments + before', () {
|
||||
test(
|
||||
'ActionRequired + Attachments + before → hasAttachment, needsAction, notSeen, before',
|
||||
() {
|
||||
final before = beforeDate();
|
||||
|
||||
final builder = MailboxFilterBuilder(
|
||||
selectedMailbox: mailbox(actionRequired: true),
|
||||
filterMessageOption: FilterMessageOption.attachments,
|
||||
);
|
||||
|
||||
final filter = builder.buildFilterCondition(
|
||||
oldestEmail: PresentationEmail(receivedAt: before),
|
||||
) as EmailFilterCondition;
|
||||
|
||||
expect(filter.hasAttachment, true);
|
||||
expect(filter.notKeyword, KeyWordIdentifier.emailSeen.value);
|
||||
expect(
|
||||
filter.hasKeyword,
|
||||
KeyWordIdentifierExtension.needsActionMail.value,
|
||||
);
|
||||
expect(filter.before, before);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
group('Edge - Null mailbox + Starred', () {
|
||||
test(
|
||||
'Null mailbox + Starred → only flagged, no inMailbox',
|
||||
() {
|
||||
const builder = MailboxFilterBuilder(
|
||||
selectedMailbox: null,
|
||||
filterMessageOption: FilterMessageOption.starred,
|
||||
);
|
||||
|
||||
final filter = builder.buildFilterCondition() as EmailFilterCondition;
|
||||
|
||||
expect(filter.hasKeyword, KeyWordIdentifier.emailFlagged.value);
|
||||
expect(filter.inMailbox, isNull);
|
||||
expect(filter.notKeyword, isNull);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user