TF-2907 Hide widget when corresponding event attribute is null

This commit is contained in:
dab246
2024-06-09 00:25:44 +07:00
committed by Dat H. Pham
parent 3aabee59da
commit 3d2ef50a00
7 changed files with 157 additions and 127 deletions
@@ -362,7 +362,10 @@ class EmailView extends GetWidget<SingleEmailController> {
presentationEmail: controller.currentEmail, presentationEmail: controller.currentEmail,
onMailtoAttendeesAction: controller.handleMailToAttendees, onMailtoAttendeesAction: controller.handleMailToAttendees,
)), )),
if (calendarEvent.getTitleEventAction(context, emailAddressSender ?? []).isNotEmpty) if (_validateDisplayEventActionBanner(
context: context,
event: calendarEvent,
emailAddressSender: emailAddressSender ?? []))
CalendarEventActionBannerWidget( CalendarEventActionBannerWidget(
calendarEvent: calendarEvent, calendarEvent: calendarEvent,
listEmailAddressSender: emailAddressSender ?? [] listEmailAddressSender: emailAddressSender ?? []
@@ -472,6 +475,20 @@ class EmailView extends GetWidget<SingleEmailController> {
); );
} }
bool _validateDisplayEventActionBanner({
required BuildContext context,
required CalendarEvent event,
required List<String> emailAddressSender
}) {
final usernameEvent = event.getUserNameEventAction(
context: context,
imagePaths: controller.imagePaths,
listEmailAddressSender: emailAddressSender);
final titleEvent = event.getTitleEventAction(context, emailAddressSender);
return usernameEvent.isNotEmpty && titleEvent.isNotEmpty;
}
void _handleMoreEmailAction({ void _handleMoreEmailAction({
required BuildContext context, required BuildContext context,
required PresentationEmail presentationEmail, required PresentationEmail presentationEmail,
@@ -110,7 +110,7 @@ extension CalendarEventExtension on CalendarEvent {
case EventMethod.refresh: case EventMethod.refresh:
case EventMethod.cancel: case EventMethod.cancel:
case EventMethod.declineCounter: case EventMethod.declineCounter:
return getOrganizerNameEvent(context); return organizerName;
case EventMethod.reply: case EventMethod.reply:
case EventMethod.counter: case EventMethod.counter:
return getAttendeeNameEvent(context, listEmailAddressSender); return getAttendeeNameEvent(context, listEmailAddressSender);
@@ -119,8 +119,6 @@ extension CalendarEventExtension on CalendarEvent {
} }
} }
String getOrganizerNameEvent(BuildContext context) => organizer?.name ?? AppLocalizations.of(context).you;
String get organizerName => organizer?.name ?? organizer?.mailto?.value ?? ''; String get organizerName => organizer?.name ?? organizer?.mailto?.value ?? '';
String getAttendeeNameEvent(BuildContext context, List<String> listEmailAddressSender) { String getAttendeeNameEvent(BuildContext context, List<String> listEmailAddressSender) {
@@ -11,9 +11,12 @@ extension ListAttendeeExtension on List<CalendarAttendee> {
.join(', '); .join(', ');
} }
List<CalendarAttendee> withoutOrganizer(CalendarOrganizer organizer) { List<CalendarAttendee> withoutOrganizer(CalendarOrganizer? organizer) {
return where((attendee) => attendee.mailto?.mailAddress != organizer.mailto) if (organizer == null) {
.whereNotNull() return this;
.toList(); }
return where((attendee) => attendee.mailto?.mailAddress != organizer.mailto)
.whereNotNull()
.toList();
} }
} }
@@ -72,12 +72,13 @@ class CalendarEventDetailWidget extends StatelessWidget {
children: [ children: [
if (calendarEvent.title?.isNotEmpty == true) if (calendarEvent.title?.isNotEmpty == true)
EventTitleWidget(title: calendarEvent.title!), EventTitleWidget(title: calendarEvent.title!),
Padding( if (eventDesc.isNotEmpty)
padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding), Padding(
child: EventBodyContentWidget( padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding),
content: eventDesc, child: EventBodyContentWidget(
isDraggableAppActive: isDraggableAppActive, content: eventDesc,
onMailtoDelegateAction: onMailtoDelegateAction)), isDraggableAppActive: isDraggableAppActive,
onMailtoDelegateAction: onMailtoDelegateAction)),
_buildEventTimeWidget(), _buildEventTimeWidget(),
if (calendarEvent.videoConferences.isNotEmpty) if (calendarEvent.videoConferences.isNotEmpty)
Padding( Padding(
@@ -93,12 +94,12 @@ class CalendarEventDetailWidget extends StatelessWidget {
onOpenNewTabAction: onOpenNewTabAction, onOpenNewTabAction: onOpenNewTabAction,
), ),
), ),
if (calendarEvent.participants?.isNotEmpty == true && calendarEvent.organizer != null) if (calendarEvent.participants?.isNotEmpty == true || calendarEvent.organizer != null)
Padding( Padding(
padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding), padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding),
child: EventAttendeeDetailWidget( child: EventAttendeeDetailWidget(
attendees: calendarEvent.participants!, attendees: calendarEvent.participants ?? [],
organizer: calendarEvent.organizer!, organizer: calendarEvent.organizer,
), ),
), ),
if (calendarEvent.isDisplayedEventReplyAction) if (calendarEvent.isDisplayedEventReplyAction)
@@ -79,27 +79,30 @@ class CalendarEventInformationWidget extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text.rich( if (calendarEvent.organizerName.isNotEmpty)
TextSpan( Padding(
style: const TextStyle( padding: const EdgeInsets.only(bottom: CalendarEventInformationWidgetStyles.space),
fontSize: CalendarEventInformationWidgetStyles.invitationMessageTextSize, child: Text.rich(
fontWeight: FontWeight.w500,
color: CalendarEventInformationWidgetStyles.invitationMessageColor
),
children: [
TextSpan( TextSpan(
text: calendarEvent.organizerName,
style: const TextStyle( style: const TextStyle(
color: CalendarEventInformationWidgetStyles.invitationMessageColor,
fontSize: CalendarEventInformationWidgetStyles.invitationMessageTextSize, fontSize: CalendarEventInformationWidgetStyles.invitationMessageTextSize,
fontWeight: FontWeight.w700 fontWeight: FontWeight.w500,
color: CalendarEventInformationWidgetStyles.invitationMessageColor
), ),
), children: [
TextSpan(text: AppLocalizations.of(context).invitationMessageCalendarInformation) TextSpan(
] text: calendarEvent.organizerName,
) style: const TextStyle(
), color: CalendarEventInformationWidgetStyles.invitationMessageColor,
const SizedBox(height: CalendarEventInformationWidgetStyles.space), fontSize: CalendarEventInformationWidgetStyles.invitationMessageTextSize,
fontWeight: FontWeight.w700
),
),
TextSpan(text: AppLocalizations.of(context).invitationMessageCalendarInformation)
]
)
),
),
if (calendarEvent.title?.isNotEmpty == true) if (calendarEvent.title?.isNotEmpty == true)
EventTitleWidget(title: calendarEvent.title!), EventTitleWidget(title: calendarEvent.title!),
_buildEventTimeInformationWidget(), _buildEventTimeInformationWidget(),
@@ -112,12 +115,12 @@ class CalendarEventInformationWidget extends StatelessWidget {
onOpenNewTabAction: onOpenNewTabAction, onOpenNewTabAction: onOpenNewTabAction,
), ),
), ),
if (calendarEvent.participants?.isNotEmpty == true && calendarEvent.organizer != null) if (calendarEvent.participants?.isNotEmpty == true || calendarEvent.organizer != null)
Padding( Padding(
padding: const EdgeInsets.only(top: CalendarEventInformationWidgetStyles.fieldTopPadding), padding: const EdgeInsets.only(top: CalendarEventInformationWidgetStyles.fieldTopPadding),
child: EventAttendeeInformationWidget( child: EventAttendeeInformationWidget(
attendees: calendarEvent.participants!, attendees: calendarEvent.participants ?? [],
organizer: calendarEvent.organizer!, organizer: calendarEvent.organizer,
), ),
), ),
if (calendarEvent.isDisplayedEventReplyAction) if (calendarEvent.isDisplayedEventReplyAction)
@@ -136,81 +139,82 @@ class CalendarEventInformationWidget extends StatelessWidget {
) )
], ],
) )
: Row( : IntrinsicHeight(
crossAxisAlignment: CrossAxisAlignment.start, child: Row(
children: [ crossAxisAlignment: CrossAxisAlignment.start,
CalendarDateIconWidget(calendarEvent: calendarEvent), children: [
Expanded(child: Container( CalendarDateIconWidget(calendarEvent: calendarEvent),
clipBehavior: Clip.antiAlias, Expanded(child: Container(
decoration: const ShapeDecoration( clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder( decoration: const ShapeDecoration(
borderRadius: BorderRadius.only( shape: RoundedRectangleBorder(
topRight: Radius.circular(CalendarEventInformationWidgetStyles.borderRadius), borderRadius: BorderRadius.only(
bottomRight: Radius.circular(CalendarEventInformationWidgetStyles.borderRadius) topRight: Radius.circular(CalendarEventInformationWidgetStyles.borderRadius),
) bottomRight: Radius.circular(CalendarEventInformationWidgetStyles.borderRadius)
),
color: Colors.white
),
padding: const EdgeInsets.all(CalendarEventInformationWidgetStyles.calendarInformationMargin),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text.rich(
TextSpan(
style: const TextStyle(
fontSize: CalendarEventInformationWidgetStyles.invitationMessageTextSize,
fontWeight: FontWeight.w500,
color: CalendarEventInformationWidgetStyles.invitationMessageColor
),
children: [
TextSpan(
text: calendarEvent.organizerName,
style: const TextStyle(
color: CalendarEventInformationWidgetStyles.invitationMessageColor,
fontSize: CalendarEventInformationWidgetStyles.invitationMessageTextSize,
fontWeight: FontWeight.w700
),
),
TextSpan(text: AppLocalizations.of(context).invitationMessageCalendarInformation)
]
) )
), ),
const SizedBox(height: CalendarEventInformationWidgetStyles.space), color: Colors.white
if (calendarEvent.title?.isNotEmpty == true) ),
EventTitleWidget(title: calendarEvent.title!), padding: const EdgeInsets.all(CalendarEventInformationWidgetStyles.calendarInformationMargin),
_buildEventTimeInformationWidget(), child: Column(
if (calendarEvent.location?.isNotEmpty == true) crossAxisAlignment: CrossAxisAlignment.start,
Padding( children: [
padding: const EdgeInsets.only(top: CalendarEventInformationWidgetStyles.fieldTopPadding), if (calendarEvent.organizerName.isNotEmpty)
child: EventLocationInformationWidget( Padding(
locationEvent: calendarEvent.location!, padding: const EdgeInsets.only(bottom: CalendarEventInformationWidgetStyles.space),
onOpenComposerAction: onOpenComposerAction, child: Text.rich(
onOpenNewTabAction: onOpenNewTabAction, TextSpan(
style: const TextStyle(
fontSize: CalendarEventInformationWidgetStyles.invitationMessageTextSize,
fontWeight: FontWeight.w500,
color: CalendarEventInformationWidgetStyles.invitationMessageColor
),
children: [
TextSpan(
text: calendarEvent.organizerName,
style: const TextStyle(
color: CalendarEventInformationWidgetStyles.invitationMessageColor,
fontSize: CalendarEventInformationWidgetStyles.invitationMessageTextSize,
fontWeight: FontWeight.w700
),
),
TextSpan(text: AppLocalizations.of(context).invitationMessageCalendarInformation)
]
)
),
), ),
), if (calendarEvent.title?.isNotEmpty == true)
if (calendarEvent.participants?.isNotEmpty == true && calendarEvent.organizer != null) EventTitleWidget(title: calendarEvent.title!),
Padding( _buildEventTimeInformationWidget(),
padding: const EdgeInsets.only(top: CalendarEventInformationWidgetStyles.fieldTopPadding), if (calendarEvent.location?.isNotEmpty == true)
child: EventAttendeeInformationWidget( Padding(
attendees: calendarEvent.participants!, padding: const EdgeInsets.only(top: CalendarEventInformationWidgetStyles.fieldTopPadding),
organizer: calendarEvent.organizer!, child: EventLocationInformationWidget(
locationEvent: calendarEvent.location!,
onOpenComposerAction: onOpenComposerAction,
onOpenNewTabAction: onOpenNewTabAction,
),
), ),
), if (calendarEvent.participants?.isNotEmpty == true || calendarEvent.organizer != null)
if (calendarEvent.isDisplayedEventReplyAction) Padding(
CalendarEventActionButtonWidget( padding: const EdgeInsets.only(top: CalendarEventInformationWidgetStyles.fieldTopPadding),
margin: EdgeInsetsDirectional.zero, child: EventAttendeeInformationWidget(
onCalendarEventReplyActionClick: onCalendarEventReplyActionClick, attendees: calendarEvent.participants ?? [],
calendarEventReplying: calendarEventReplying, organizer: calendarEvent.organizer,
presentationEmail: presentationEmail, ),
onMailToAttendeesAction: () => onMailtoAttendeesAction?.call(
calendarEvent.organizer,
calendarEvent.participants,
), ),
), if (calendarEvent.isDisplayedEventReplyAction)
], CalendarEventActionButtonWidget(
), margin: EdgeInsetsDirectional.zero,
)) onCalendarEventReplyActionClick: onCalendarEventReplyActionClick,
], calendarEventReplying: calendarEventReplying,
presentationEmail: presentationEmail,
),
],
),
))
],
),
), ),
); );
} }
@@ -15,7 +15,7 @@ class EventAttendeeDetailWidget extends StatefulWidget {
static const int maxAttendeeDisplayed = 6; static const int maxAttendeeDisplayed = 6;
final List<CalendarAttendee> attendees; final List<CalendarAttendee> attendees;
final CalendarOrganizer organizer; final CalendarOrganizer? organizer;
const EventAttendeeDetailWidget({ const EventAttendeeDetailWidget({
super.key, super.key,
@@ -59,10 +59,12 @@ class _EventAttendeeDetailWidgetState extends State<EventAttendeeDetailWidget> {
Expanded(child: Column( Expanded(child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
OrganizerWidget(organizer: widget.organizer), if (widget.organizer != null)
..._attendeesDisplayed OrganizerWidget(organizer: widget.organizer!),
.map((attendee) => AttendeeWidget(attendee: attendee, listAttendees: _attendeesDisplayed)) if (_attendeesDisplayed.isNotEmpty)
.toList(), ..._attendeesDisplayed
.map((attendee) => AttendeeWidget(attendee: attendee, listAttendees: _attendeesDisplayed))
.toList(),
if (!_isShowAllAttendee) if (!_isShowAllAttendee)
Padding( Padding(
padding: const EdgeInsets.only(top: EventAttendeeDetailWidgetStyles.fieldTopPadding), padding: const EdgeInsets.only(top: EventAttendeeDetailWidgetStyles.fieldTopPadding),
@@ -11,9 +11,11 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class EventAttendeeInformationWidget extends StatelessWidget { class EventAttendeeInformationWidget extends StatelessWidget {
final List<CalendarAttendee> attendees; final List<CalendarAttendee> attendees;
final CalendarOrganizer organizer; final CalendarOrganizer? organizer;
const EventAttendeeInformationWidget({ final _responsiveUtils = Get.find<ResponsiveUtils>();
EventAttendeeInformationWidget({
super.key, super.key,
required this.attendees, required this.attendees,
required this.organizer required this.organizer
@@ -21,7 +23,6 @@ class EventAttendeeInformationWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final responsiveUtils = Get.find<ResponsiveUtils>();
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@@ -44,22 +45,26 @@ class EventAttendeeInformationWidget extends StatelessWidget {
color: EventAttendeeInformationWidgetStyles.valueColor color: EventAttendeeInformationWidgetStyles.valueColor
), ),
children: [ children: [
TextSpan( if (organizer != null)
text: '${organizer.mailto?.value} (${AppLocalizations.of(context).organizer})', ...[
style: const TextStyle( TextSpan(
color: EventAttendeeInformationWidgetStyles.valueOrganizerColor, text: '${organizer!.mailto?.value} (${AppLocalizations.of(context).organizer})',
fontSize: EventAttendeeInformationWidgetStyles.textSize, style: const TextStyle(
fontWeight: FontWeight.w500 color: EventAttendeeInformationWidgetStyles.valueOrganizerColor,
), fontSize: EventAttendeeInformationWidgetStyles.textSize,
), fontWeight: FontWeight.w500
const TextSpan(text: ', '), ),
TextSpan(text: attendees.withoutOrganizer(organizer).mailtoAsString) ),
const TextSpan(text: ', '),
],
if (attendees.isNotEmpty)
TextSpan(text: attendees.withoutOrganizer(organizer).mailtoAsString)
] ]
), ),
overflow: responsiveUtils.isPortraitMobile(context) overflow: _responsiveUtils.isPortraitMobile(context)
? TextOverflow.clip ? TextOverflow.clip
: TextOverflow.ellipsis, : TextOverflow.ellipsis,
maxLines: responsiveUtils.isPortraitMobile(context) ? null : 2, maxLines: _responsiveUtils.isPortraitMobile(context) ? null : 2,
)) ))
], ],
); );