Add presentation layer for mailbox, mail, message
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
import 'package:core/presentation/utils/responsive_utils.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/thread_controller.dart';
|
||||
|
||||
class ThreadBindings extends Bindings {
|
||||
@override
|
||||
void dependencies() {
|
||||
Get.lazyPut(() => ThreadController(Get.find<ResponsiveUtils>()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import 'package:core/core.dart';
|
||||
import 'package:core/presentation/utils/responsive_utils.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/base/base_controller.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
|
||||
import 'package:tmail_ui_user/main/routes/app_routes.dart';
|
||||
|
||||
class ThreadController extends BaseController {
|
||||
|
||||
final ResponsiveUtils responsiveUtils;
|
||||
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
|
||||
|
||||
final presentationMailCurrent = PresentationThread.createThreadEmpty().obs;
|
||||
|
||||
ThreadController(this.responsiveUtils);
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
mailboxDashBoardController.scaffoldKey.currentState?.openEndDrawer();
|
||||
}
|
||||
|
||||
SelectMode getSelectMode(PresentationThread presentationThread) {
|
||||
return presentationMailCurrent.value.id == presentationThread.id
|
||||
? SelectMode.ACTIVE
|
||||
: SelectMode.INACTIVE;
|
||||
}
|
||||
|
||||
void selectMail(BuildContext context, PresentationThread presentationMailSelected) {
|
||||
presentationMailCurrent.value = presentationMailSelected;
|
||||
mailboxDashBoardController.mailCurrent.value = presentationMailSelected;
|
||||
|
||||
if (!responsiveUtils.isDesktop(context)) {
|
||||
goToMail(context);
|
||||
}
|
||||
}
|
||||
|
||||
void goToMailbox({required GlobalKey<ScaffoldState> keyWidgetMailboxContainer}) {
|
||||
keyWidgetMailboxContainer.currentState?.openDrawer();
|
||||
}
|
||||
|
||||
void goToMail(BuildContext context) {
|
||||
Get.toNamed(AppRoutes.MAIL);
|
||||
}
|
||||
|
||||
@override
|
||||
void onData(Either<Failure, Success> newState) {
|
||||
super.onData(newState);
|
||||
}
|
||||
|
||||
@override
|
||||
void onDone() {}
|
||||
|
||||
@override
|
||||
void onError(error) {}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
import 'package:core/core.dart';
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/thread_controller.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/thread_tile_builder.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class ThreadView extends GetWidget<ThreadController> {
|
||||
|
||||
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
|
||||
final responsiveUtils = Get.find<ResponsiveUtils>();
|
||||
final imagePaths = Get.find<ImagePaths>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
backgroundColor: AppColor.primaryLightColor,
|
||||
body: SafeArea(
|
||||
right: false,
|
||||
left: false,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Obx(() => _buildAppBarMailboxListMail(context)),
|
||||
Expanded(child: _buildListMail(context)),
|
||||
])
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildAppBarMailboxListMail(BuildContext context) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(left: 16, top: 8.0, right: 16),
|
||||
child: AppBarThreadWidgetBuilder(
|
||||
context,
|
||||
imagePaths,
|
||||
responsiveUtils,
|
||||
mailboxDashBoardController.mailboxCurrent.value)
|
||||
.onOpenListMailboxActionClick(() => controller.goToMailbox(keyWidgetMailboxContainer: mailboxDashBoardController.scaffoldKey))
|
||||
.build());
|
||||
}
|
||||
|
||||
Widget _buildListMail(BuildContext context) {
|
||||
return Container(
|
||||
margin: EdgeInsets.zero,
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.zero,
|
||||
color: responsiveUtils.isMobile(context) ? AppColor.bgMailboxListMail : Colors.white,
|
||||
child: Obx(() => controller.viewState.value.fold(
|
||||
(failure) => _buildEmptyThread(context),
|
||||
(success) => _buildListThreadBody(context, []))
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildListThreadBody(BuildContext context, List<PresentationThread> listThread) {
|
||||
if (listThread.isEmpty) {
|
||||
return _buildEmptyThread(context);
|
||||
} else {
|
||||
return ListView.builder(
|
||||
padding: EdgeInsets.only(top: 16, left: 16, right: 16),
|
||||
key: Key('thread_list'),
|
||||
itemCount: listThread.length,
|
||||
itemBuilder: (context, index) =>
|
||||
Obx(() => ThreadTileBuilder(
|
||||
imagePaths,
|
||||
controller.getSelectMode(listThread[index]),
|
||||
listThread[index])
|
||||
.onOpenMailAction(() => controller.selectMail(context, listThread[index]))
|
||||
.build()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildEmptyThread(BuildContext context) {
|
||||
return Text(
|
||||
AppLocalizations.of(context).no_threads,
|
||||
maxLines: 1,
|
||||
style: TextStyle(fontSize: 25, color: AppColor.mailboxTextColor, fontWeight: FontWeight.bold));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:model/mailbox/presentation_mailbox.dart';
|
||||
|
||||
typedef OnOpenSearchMailActionClick = void Function();
|
||||
typedef OnOpenListMailboxActionClick = void Function();
|
||||
typedef OnOpenUserInformationActionClick = void Function();
|
||||
|
||||
class AppBarThreadWidgetBuilder {
|
||||
OnOpenSearchMailActionClick? _onOpenSearchMailActionClick;
|
||||
OnOpenListMailboxActionClick? _onOpenListMailboxActionClick;
|
||||
OnOpenUserInformationActionClick? _onOpenUserInformationActionClick;
|
||||
|
||||
final BuildContext _context;
|
||||
final ImagePaths _imagePaths;
|
||||
final ResponsiveUtils _responsiveUtils;
|
||||
final PresentationMailbox _presentationMailbox;
|
||||
|
||||
AppBarThreadWidgetBuilder(
|
||||
this._context,
|
||||
this._imagePaths,
|
||||
this._responsiveUtils,
|
||||
this._presentationMailbox
|
||||
);
|
||||
|
||||
AppBarThreadWidgetBuilder onOpenUserInformationAction(
|
||||
OnOpenUserInformationActionClick onOpenUserInformationActionClick) {
|
||||
_onOpenUserInformationActionClick = onOpenUserInformationActionClick;
|
||||
return this;
|
||||
}
|
||||
|
||||
AppBarThreadWidgetBuilder onOpenSearchMailActionClick(
|
||||
OnOpenSearchMailActionClick onOpenSearchMailActionClick) {
|
||||
_onOpenSearchMailActionClick = onOpenSearchMailActionClick;
|
||||
return this;
|
||||
}
|
||||
|
||||
AppBarThreadWidgetBuilder onOpenListMailboxActionClick(
|
||||
OnOpenListMailboxActionClick onOpenListMailboxActionClick) {
|
||||
_onOpenListMailboxActionClick = onOpenListMailboxActionClick;
|
||||
return this;
|
||||
}
|
||||
|
||||
Widget build() {
|
||||
return Container(
|
||||
key: Key('app_bar_thread_widget'),
|
||||
alignment: Alignment.center,
|
||||
color: Colors.white,
|
||||
child: MediaQuery(
|
||||
data: MediaQueryData(padding: EdgeInsets.zero),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
if (_responsiveUtils.isMobile(_context)) _buildIconUser(),
|
||||
Expanded(child: _buildContentCenterAppBar()),
|
||||
_buildIconSearch(),
|
||||
]
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildIconUser() {
|
||||
return GestureDetector(
|
||||
onTap: () => {
|
||||
if (_onOpenUserInformationActionClick != null) {
|
||||
_onOpenUserInformationActionClick!()
|
||||
}},
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(left: _responsiveUtils.isMobile(_context) ? 24 : 0),
|
||||
child: SvgPicture.asset(_imagePaths.icTMailLogo, width: 24, height: 24, fit: BoxFit.fill)));
|
||||
}
|
||||
|
||||
Widget _buildIconSearch() {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(left: 16, right: 0),
|
||||
child: IconButton(
|
||||
icon: SvgPicture.asset(_imagePaths.icSearch, width: 24, height: 24, fit: BoxFit.fill),
|
||||
onPressed: () => {
|
||||
if (_onOpenSearchMailActionClick != null) {
|
||||
_onOpenSearchMailActionClick!()
|
||||
}
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
Widget _buildContentCenterAppBar() {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () => {
|
||||
if (_onOpenListMailboxActionClick != null) {
|
||||
_onOpenListMailboxActionClick!()
|
||||
}},
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(left: 16),
|
||||
child: Text(
|
||||
'${_presentationMailbox.name?.name}',
|
||||
maxLines: 1,
|
||||
style: TextStyle(fontSize: 22, color: AppColor.titleAppBarMailboxListMail, fontWeight: FontWeight.w500),
|
||||
))),
|
||||
if(_presentationMailbox.getCountUnReadEmails().isNotEmpty)
|
||||
Container(
|
||||
margin: EdgeInsets.only(left: 9),
|
||||
padding: EdgeInsets.only(left: 8, right: 8, top: 2, bottom: 2),
|
||||
decoration:BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
color: AppColor.bgNotifyCountAppBarMailboxListMail),
|
||||
child: Text(
|
||||
'${_presentationMailbox.getCountUnReadEmails()} new',
|
||||
maxLines: 1,
|
||||
style: TextStyle(fontSize: 10, color: AppColor.notifyCountAppBarMailboxListMail, fontWeight: FontWeight.w500),
|
||||
))
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:model/model.dart';
|
||||
|
||||
typedef OnOpenMailActionClick = void Function();
|
||||
|
||||
class ThreadTileBuilder {
|
||||
|
||||
final SelectMode _selectMode;
|
||||
final ImagePaths _imagePaths;
|
||||
final PresentationThread _presentationThread;
|
||||
|
||||
OnOpenMailActionClick? _onOpenMailActionClick;
|
||||
|
||||
ThreadTileBuilder(
|
||||
this._imagePaths,
|
||||
this._selectMode,
|
||||
this._presentationThread,
|
||||
);
|
||||
|
||||
ThreadTileBuilder onOpenMailAction(OnOpenMailActionClick onOpenMailActionClick) {
|
||||
_onOpenMailActionClick = onOpenMailActionClick;
|
||||
return this;
|
||||
}
|
||||
|
||||
Widget build() {
|
||||
return Theme(
|
||||
data: ThemeData(
|
||||
splashColor: Colors.transparent,
|
||||
highlightColor: Colors.transparent),
|
||||
child: Container(
|
||||
key: Key('thread_tile'),
|
||||
margin: EdgeInsets.only(bottom: 10),
|
||||
padding: EdgeInsets.only(left: 16, right: 16, top: 10, bottom: 10),
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
color: _selectMode== SelectMode.ACTIVE
|
||||
? AppColor.mailboxSelectedBackgroundColor
|
||||
: AppColor.mailboxBackgroundColor),
|
||||
child: MediaQuery(
|
||||
data: MediaQueryData(padding: EdgeInsets.zero),
|
||||
child: ListTile(
|
||||
focusColor: AppColor.primaryLightColor,
|
||||
hoverColor: AppColor.primaryLightColor,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
onTap: () => {
|
||||
if (_onOpenMailActionClick != null) {
|
||||
_onOpenMailActionClick!()
|
||||
}
|
||||
},
|
||||
leading: Transform(
|
||||
transform: Matrix4.translationValues(0.0, -12.0, 0.0),
|
||||
child: SvgPicture.asset(
|
||||
_imagePaths.icTMailLogo,
|
||||
width: 32,
|
||||
height: 32,
|
||||
color: _selectMode == SelectMode.ACTIVE ? AppColor.mailboxSelectedIconColor : AppColor.mailboxIconColor,
|
||||
fit: BoxFit.fill)),
|
||||
title: Padding(
|
||||
padding: EdgeInsets.only(left: 0),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
'',
|
||||
maxLines: 1,
|
||||
overflow:TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: _selectMode == SelectMode.ACTIVE ? AppColor.mailboxSelectedTextColor : AppColor.mailboxTextColor,
|
||||
fontWeight: FontWeight.bold))),
|
||||
Text(
|
||||
'',
|
||||
maxLines: 1,
|
||||
overflow:TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: _selectMode == SelectMode.ACTIVE ? AppColor.mailboxSelectedTextColor : AppColor.mailboxTextColor))
|
||||
],
|
||||
)
|
||||
),
|
||||
subtitle: Padding(
|
||||
padding: EdgeInsets.only(left: 0, top: 8),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 3),
|
||||
child: Text(
|
||||
'',
|
||||
maxLines: 1,
|
||||
overflow:TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: AppColor.appColor,
|
||||
fontWeight: FontWeight.bold))),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
'${_presentationThread.message}',
|
||||
maxLines: 1,
|
||||
overflow:TextOverflow.ellipsis,
|
||||
style: TextStyle(fontSize: 12, color: AppColor.baseTextColor))),
|
||||
ButtonBuilder(_imagePaths.icCalendar).build(),
|
||||
SizedBox(width: 12),
|
||||
ButtonBuilder(_imagePaths.icShare).build(),
|
||||
SizedBox(width: 12),
|
||||
ButtonBuilder(_imagePaths.icStar).build(),
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user