Files
workavia-mail-front/lib/features/thread_detail/presentation/thread_detail_view.dart
T
DatDang 58a576adeb TF-3643 Thread Detail get emails meta data method
TF-3643 Thread Detail cache email with thread id

TF-3643 Thread Detail view thread detail

TF-3643 Thread Detail [Part 2 fixup] remove ThreadDetailController dependency from MailboxDashboardController

TF-3643 Thread Detail [Part 2 fixup] remove EmailSupervisorController dependency from ThreadDetailController

TF-3643 Thread Detail [Part 2 fixup] move isSearchRunning check into ThreadDetailController

TF-3643 Thread Detail [Part 2 fixup] ensure GetEmailsByIdsInteractor performance

TF-3643 Thread Detail [Part 2 fixup] unit test loadMoreThreadDetailEmails

TF-3643 Thread Detail [Part 2 fixup] unit test getEmailIdsToLoad

TF-3643 Thread Detail [Part 2 fixup] optimize ThreadDetailBinding bindingsDataSource

TF-3643 Thread Detail [Part 2 fixup] optimize getThreadDetailLoadingView

TF-3643 Thread Detail [Part 2 fixup] readd unique ValueKey for HtmlContentViewerOnWebWidget

TF-3643 Thread Detail [Part 2 fixup] unit test initializeThreadDetailEmails

TF-3643 Thread Detail [Part 3 fixup] Update private action button methods

TF-3643 Thread Detail [Part 4 fixup] Collapsed email preview 65 characters max

TF-3643 Thread Detail [Part 4 fixup] Remove personal scripts

TF-3643 Thread Detail move EmailInThreadStatus into PresentationEmail

TF-3643 Thread Detail refactor toggle collapse expand

TF-3643 Thread Detail EmailViewAppBarWidget required parameters

TF-3643 Thread Detail tap avatar toggle expansion

TF-3643 Thread Detail fix cannot open single email

TF-3643 Thread Detail fix open thread first time blank view

TF-3643 Thread Detail fix thread detail UI

TF-3643 Thread Detail fix round bottom view

TF-3643 Thread Detail fix round bottom view

TF-3643 Thread Detail bottom actions depend on current expanded email

TF-3643 Thread Detail hide next previous actions

TF-3643 Thread Detail fix load more show initial loading view

TF-3643 Thread Detail fix cannot view single email

TF-3643 Thread Detail fix bottom place holder not aligned

TF-3643 Thread Detail fix back to search view

TF-3643 Thread Detail fix display 65 character preview collapsed email

TF-3643 Thread Detail fix search not work

TF-3643 Thread Detail fix bottom place holder UI

TF-3643 Thread Detail fix expand view

TF-3643 Thread Detail jump to top of last email view

TF-3643 Thread Detail remove toMe condition of filtering thread

TF-3643 Thread Detail fix sort thread detail

TF-3643 Thread Detail fix assert not work in release

TF-3643 Thread Detail add load more test case <20

TF-3643 Thread Detail remove the use of currentThreadId

TF-3643 Thread Detail remove the use of selectedEmail in SingleEmailController

TF-3643 Thread Detail fix unit test SingleEmailController calendar

TF-3643 Thread Detail disable 2 way scroll control

TF-3643 Thread Detail allow thread to load sent email incase thread only contains 1 email

TF-3643 Thread Detail disable single email page view

TF-3643 Thread Detail update emailsNotLoadedCount name

TF-3643 Thread Detail remove collapsed email char limit

TF-3643 Thread Detail fix CI

TF-3643 Thread Detail unit test handleGetEmailIdsByThreadIdSuccess

TF-3643 Thread Detail make _currentEmailId private

TF-3643 Thread Detail fix search click users

TF-3643 Thread Detail fix scroll jump

TF-3643 Thread Detail fix scroll jump

TF-3643 Thread Detail fix web back action

TF-3643 Thread Detail round bottom actions

TF-3643 Thread Detail fix tablet large empty email

TF-3643 Thread Detail fix email subject selectable

TF-3643 Thread Detail fix email single view with top divider

TF-3643 Thread Detail fix email cache threadId missing

TF-3643 Thread Detail fix filter sent email in thread details

TF-3643 Thread Detail fix select text

TF-3643 Thread Detail fix subject alignment

TF-3643 Thread Detail fix subject alignment

TF-3643 Thread Detail fix tablet large empty email

TF-3643 Thread Detail add nullcheck for _jumpScrollViewToTopOfEmail

TF-3643 Thread Detail decouple ThreadDetailController from SingleEmailController

TF-3643 Thread Detail combine emailIds to emailIdsPresentation

TF-3643 Thread Detail remove currentEmailLoaded obx listener of SingleEmailController

TF-3643 Thread Detail replace threadAction with an email ui action

TF-3643 Thread Detail fix top and bottom bar delay displaying

TF-3643 Thread Detail update ReplyForwardBottomBarAction to PerformEmailActionInThreadDetailAction

TF-3643 Thread Detail use getOwnEmailAddress in ThreadDetailAppBar

TF-3643 Thread Detail add TextOverflow.ellipsis to EmailSubjectWidget

TF-3643 Thread Detail fix round border threadDetailLoadingView
2025-07-21 05:34:53 +07:00

199 lines
7.9 KiB
Dart

import 'package:collection/collection.dart';
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:dartz/dartz.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/email/presentation/action/email_ui_action.dart';
import 'package:tmail_ui_user/features/email/presentation/controller/single_email_controller.dart';
import 'package:tmail_ui_user/features/email/presentation/email_view.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/email_view_bottom_bar_widget.dart';
import 'package:tmail_ui_user/features/thread_detail/domain/state/get_thread_by_id_state.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/close_thread_detail_action.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/get_thread_detail_loading_view.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/extension/get_thread_details_email_views.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/thread_detail_controller.dart';
import 'package:tmail_ui_user/features/thread_detail/presentation/widgets/thread_detail_app_bar.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
class ThreadDetailView extends GetWidget<ThreadDetailController> {
const ThreadDetailView({super.key});
@override
Widget build(BuildContext context) {
final multipleEmailsView = SelectionArea(child: SafeArea(
child: Column(
children: [
Obx(() {
final currentViewState = controller.viewState.value.fold(id, id);
if (currentViewState is GettingThreadById) {
return const SizedBox.shrink();
}
return ThreadDetailAppBar(
responsiveUtils: controller.responsiveUtils,
imagePaths: controller.imagePaths,
isSearchRunning: controller.isSearchRunning,
closeThreadDetailAction: controller.closeThreadDetailAction,
lastEmailOfThread: controller.emailIdsPresentation.values.lastOrNull,
ownUserName: controller.session?.getOwnEmailAddress() ?? '',
mailboxContain: _getMailboxContain(),
emailLoaded: getBinding<SingleEmailController>(
tag: controller.emailIdsPresentation.keys.lastOrNull?.id.value
)?.currentEmailLoaded.value,
onEmailActionClick: (email, action) {
// TODO: Next PR
},
onMoreActionClick: (p0, p1) {
// TODO: Next PR
},
);
}),
Obx(() => controller.getThreadDetailLoadingView(
isResponsiveDesktop: controller.responsiveUtils.isDesktop(context),
)),
Obx(() {
return controller.viewState.value.fold(
(failure) => const SizedBox.shrink(),
(success) {
if (success is GettingThreadById) {
return const SizedBox.shrink();
}
return Expanded(
child: Padding(
padding: _padding(context),
child: Stack(
children: [
const Positioned.fill(
child: ColoredBox(color: Colors.white),
),
SingleChildScrollView(
controller: controller.scrollController,
child: Column(
mainAxisSize: MainAxisSize.min,
children: controller.getThreadDetailEmailViews()
),
),
],
),
),
);
},
);
}),
Obx(() {
final currentViewState = controller.viewState.value.fold(id, id);
if (currentViewState is GettingThreadById) {
return const SizedBox.shrink();
}
final expandedEmailId = controller.currentExpandedEmailId.value;
if (expandedEmailId == null) {
return _roundBottomPlaceHolder(
isDesktop: controller.responsiveUtils.isDesktop(context),
);
}
final expandedPresentationEmail = controller.emailIdsPresentation[expandedEmailId];
if (expandedPresentationEmail == null) {
return _roundBottomPlaceHolder(
isDesktop: controller.responsiveUtils.isDesktop(context),
);
}
final currentEmailLoaded = controller.currentEmailLoaded.value;
if (currentEmailLoaded == null) {
return _roundBottomPlaceHolder(
isDesktop: controller.responsiveUtils.isDesktop(context),
);
}
return Padding(
padding: controller.responsiveUtils.isDesktop(context)
? const EdgeInsetsDirectional.only(end: 16)
: EdgeInsets.zero,
child: ClipRRect(
borderRadius: const BorderRadius.vertical(
bottom: Radius.circular(20),
),
child: EmailViewBottomBarWidget(
key: const Key('email_view_button_bar'),
imagePaths: controller.imagePaths,
responsiveUtils: controller.responsiveUtils,
emailLoaded: currentEmailLoaded,
presentationEmail: expandedPresentationEmail,
userName: controller.session?.getOwnEmailAddress() ?? '',
emailActionCallback: (action, email) {
controller.mailboxDashBoardController
..dispatchEmailUIAction(PerformEmailActionInThreadDetailAction(
emailActionType: action,
presentationEmail: email,
))
..dispatchEmailUIAction(EmailUIAction());
},
bottomBarDecoration: const BoxDecoration(
color: Colors.white,
border: Border(
top: BorderSide(color: AppColor.colorDividerEmailView),
),
),
padding: EdgeInsets.zero,
),
),
);
}),
if (controller.responsiveUtils.isDesktop(context))
const SizedBox(height: 16),
],
),
));
return Obx(() {
final currentViewState = controller.viewState.value.fold(id, id);
if (currentViewState is GettingThreadById &&
controller.responsiveUtils.isTabletLarge(context)) {
return controller.getThreadDetailLoadingView(isResponsiveDesktop: false);
}
if (controller.emailIdsPresentation.length == 1 &&
controller.emailIdsPresentation.values.firstOrNull != null) {
return EmailView(
emailId: controller.emailIdsPresentation.values.firstOrNull?.id,
);
}
return multipleEmailsView;
});
}
EdgeInsetsGeometry _padding(BuildContext context) {
if (controller.responsiveUtils.isDesktop(context)) {
return const EdgeInsetsDirectional.only(end: 16);
}
return EdgeInsets.zero;
}
PresentationMailbox? _getMailboxContain() {
if (controller.isSearchRunning) {
return null;
}
return controller.mailboxDashBoardController.selectedMailbox.value;
}
Widget _roundBottomPlaceHolder({required bool isDesktop}) {
return Container(
height: 40,
margin: isDesktop
? const EdgeInsetsDirectional.only(end: 16)
: EdgeInsets.zero,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(
bottom: Radius.circular(20),
),
)
);
}
}