TF-4093 Make interface more compact

This commit is contained in:
dab246
2025-10-16 10:00:41 +07:00
committed by Dat H. Pham
parent 804f5e2a02
commit 7d80557582
23 changed files with 373 additions and 272 deletions
@@ -67,37 +67,31 @@ extension GetThreadDetailEmailViews on ThreadDetailController {
}
if (isFirstEmailInThreadDetail) {
return Padding(
padding: const EdgeInsetsDirectional.only(bottom: 16),
child: EmailView(
key: PlatformInfo.isWeb
? GlobalObjectKey(presentationEmail.id?.id.value ?? '')
: null,
isInsideThreadDetailView: true,
emailId: presentationEmail.id,
isFirstEmailInThreadDetail: true,
threadSubject: emailIdsPresentation.values.last?.subject,
onToggleThreadDetailCollapseExpand: () {
toggleThreadDetailCollapseExpand(presentationEmail);
},
scrollController: scrollController,
),
);
}
return Padding(
padding: const EdgeInsetsDirectional.only(bottom: 16),
child: EmailView(
return EmailView(
key: PlatformInfo.isWeb
? GlobalObjectKey(presentationEmail.id?.id.value ?? '')
: null,
isInsideThreadDetailView: true,
emailId: presentationEmail.id,
isFirstEmailInThreadDetail: true,
threadSubject: emailIdsPresentation.values.last?.subject,
onToggleThreadDetailCollapseExpand: () {
toggleThreadDetailCollapseExpand(presentationEmail);
},
scrollController: scrollController,
),
);
}
return EmailView(
key: PlatformInfo.isWeb
? GlobalObjectKey(presentationEmail.id?.id.value ?? '')
: null,
isInsideThreadDetailView: true,
emailId: presentationEmail.id,
onToggleThreadDetailCollapseExpand: () {
toggleThreadDetailCollapseExpand(presentationEmail);
},
scrollController: scrollController,
);
}).toList();
}
@@ -108,7 +108,7 @@ class ThreadDetailAppBar extends StatelessWidget {
if (isMobile) {
backButton = Expanded(
child: Align(
alignment: Alignment.centerLeft,
alignment: AlignmentDirectional.centerStart,
child: backButton,
),
);
@@ -141,7 +141,9 @@ class ThreadDetailAppBar extends StatelessWidget {
: EmailViewAppBarWidgetStyles.height,
padding: PlatformInfo.isIOS
? EmailViewAppBarWidgetStyles.paddingIOS(context, responsiveUtils)
: EmailViewAppBarWidgetStyles.padding,
: isMobile
? EmailViewAppBarWidgetStyles.mobilePadding
: EmailViewAppBarWidgetStyles.padding,
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(
@@ -2,7 +2,6 @@ import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:core/presentation/views/text/text_overflow_builder.dart';
import 'package:flutter/material.dart';
import 'package:model/email/presentation_email.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
@@ -40,6 +39,8 @@ class ThreadDetailCollapsedEmail extends StatelessWidget {
@override
Widget build(BuildContext context) {
final isMobileResponsive = responsiveUtils.isMobile(context);
return DecoratedBox(
decoration: const BoxDecoration(
color: Colors.white,
@@ -57,9 +58,10 @@ class ThreadDetailCollapsedEmail extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: [
if (showSubject)
EmailSubjectWidget(presentationEmail: presentationEmail)
else
const SizedBox(height: 16),
EmailSubjectWidget(
presentationEmail: presentationEmail,
isMobileResponsive: isMobileResponsive,
),
InformationSenderAndReceiverBuilder(
emailSelected: presentationEmail,
responsiveUtils: responsiveUtils,
@@ -71,22 +73,27 @@ class ThreadDetailCollapsedEmail extends StatelessWidget {
showRecipients: false,
mailboxContain: mailboxContain,
showUnreadVisualization: true,
isInsideThreadCollapsed: true,
),
Padding(
padding: const EdgeInsets.all(16),
child: TextOverflowBuilder(
padding: isMobileResponsive
? const EdgeInsetsDirectional.only(
top: 12,
bottom: 21,
start: 12,
end: 12,
)
: const EdgeInsetsDirectional.only(
top: 8,
bottom: 24,
start: 16,
end: 16,
),
child: Text(
preview,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: ThemeUtils.textStyleBodyBody1(
fontWeight: presentationEmail.hasRead
? FontWeight.normal
: FontWeight.w600,
fontSize: presentationEmail.hasRead ? null : 15,
).copyWith(
height: presentationEmail.hasRead ? 24 / 16 : 20 / 15,
letterSpacing: presentationEmail.hasRead ? -0.16 : 0,
),
style: _getPreviewTextStyle(isMobileResponsive),
),
),
],
@@ -94,4 +101,29 @@ class ThreadDetailCollapsedEmail extends StatelessWidget {
),
);
}
TextStyle _getPreviewTextStyle(bool isMobileResponsive) {
if (isMobileResponsive) {
return presentationEmail.hasRead
? ThemeUtils.textStyleInter400.copyWith(
color: Colors.black,
fontSize: 16,
height: 24 / 16,
letterSpacing: -0.16,
)
: ThemeUtils.textStyleInter600().copyWith(
color: Colors.black,
fontSize: 16,
height: 24 / 16,
letterSpacing: -0.16,
);
} else {
return presentationEmail.hasRead
? ThemeUtils.textStyleBodyBody3().copyWith(color: Colors.black)
: ThemeUtils.textStyleBodyBody3().copyWith(
color: Colors.black,
fontWeight: FontWeight.w600,
);
}
}
}
@@ -1,5 +1,7 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:core/presentation/views/loading/cupertino_loading_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
@@ -29,6 +31,7 @@ class ThreadDetailLoadMoreCircle extends StatefulWidget {
class _ThreadDetailLoadMoreCircleState extends State<ThreadDetailLoadMoreCircle> {
final _isHover = ValueNotifier(false);
final threadDetailController = Get.find<ThreadDetailController>();
final _responsiveUtils = Get.find<ResponsiveUtils>();
@override
void dispose() {
@@ -38,8 +41,10 @@ class _ThreadDetailLoadMoreCircleState extends State<ThreadDetailLoadMoreCircle>
@override
Widget build(BuildContext context) {
final isMobileResponsive = _responsiveUtils.isMobile(context);
return Container(
padding: const EdgeInsets.symmetric(vertical: 16),
padding: EdgeInsets.symmetric(vertical: isMobileResponsive ? 12 : 16),
color: Colors.white,
child: Stack(
alignment: Alignment.centerLeft,
@@ -57,9 +62,11 @@ class _ThreadDetailLoadMoreCircleState extends State<ThreadDetailLoadMoreCircle>
onTap: widget.onTap,
onHover: (value) => _isHover.value = value,
child: Container(
margin: const EdgeInsetsDirectional.only(start: 16),
width: 56,
height: 56,
margin: EdgeInsetsDirectional.only(
start: isMobileResponsive ? 12 : 16,
),
width: isMobileResponsive ? 44 : 32,
height: isMobileResponsive ? 44 : 32,
decoration: BoxDecoration(
border: Border.all(
color: AppColor.colorDividerEmailView,
@@ -80,10 +87,10 @@ class _ThreadDetailLoadMoreCircleState extends State<ThreadDetailLoadMoreCircle>
);
if (isLoading) {
return const SizedBox(
width: 24,
height: 24,
child: CupertinoLoadingWidget(),
return SizedBox(
width: isMobileResponsive ? 24 : 16,
height: isMobileResponsive ? 24 : 16,
child: const CupertinoLoadingWidget(),
);
}
@@ -93,15 +100,19 @@ class _ThreadDetailLoadMoreCircleState extends State<ThreadDetailLoadMoreCircle>
return Text(
'${widget.count}',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.normal,
height: 24 / 16,
letterSpacing: -0.1,
style: ThemeUtils.textStyleBodyBody3().copyWith(
color: Colors.black,
fontSize: isMobileResponsive ? 14 : 13,
height: isMobileResponsive ? 18 / 14 : 16 / 13,
),
);
});
},
child: SvgPicture.asset(widget.imagePaths.icExpandArrows),
child: SvgPicture.asset(
widget.imagePaths.icExpandArrows,
width: isMobileResponsive ? 20 : 16,
height: isMobileResponsive ? 20 : 16,
),
),
),
),