TF-3792 Hide buttons of blue bar in case of event not belong to this account and change

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2025-06-20 10:42:21 +07:00
committed by Dat H. Pham
parent 3e48d9cf92
commit 8579eb2518
18 changed files with 377 additions and 396 deletions
@@ -1,10 +1,6 @@
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/views/button/tmail_button_widget.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/mail/calendar/attendance/calendar_event_attendance.dart';
import 'package:jmap_dart_client/jmap/mail/calendar/properties/event_method.dart';
import 'package:tmail_ui_user/features/email/domain/extensions/list_event_actions_extension.dart';
import 'package:tmail_ui_user/features/email/domain/model/event_action.dart';
import 'package:tmail_ui_user/features/email/presentation/styles/calendar_event_action_button_widget_styles.dart';
@@ -12,22 +8,20 @@ typedef OnCalendarEventReplyActionClick = void Function(EventActionType eventAct
class CalendarEventActionButtonWidget extends StatelessWidget {
final EdgeInsetsGeometry? margin;
final List<EventActionType> eventActions;
final OnCalendarEventReplyActionClick onCalendarEventReplyActionClick;
final bool calendarEventReplying;
final EventMethod? eventMethod;
final AttendanceStatus? attendanceStatus;
final bool isPortraitMobile;
final VoidCallback? onMailToAttendeesAction;
final _responsiveUtils = Get.find<ResponsiveUtils>();
CalendarEventActionButtonWidget({
const CalendarEventActionButtonWidget({
super.key,
required this.eventActions,
required this.onCalendarEventReplyActionClick,
required this.calendarEventReplying,
required this.eventMethod,
this.margin,
this.attendanceStatus,
this.isPortraitMobile = false,
this.onMailToAttendeesAction,
});
@@ -35,15 +29,13 @@ class CalendarEventActionButtonWidget extends StatelessWidget {
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: margin ?? CalendarEventActionButtonWidgetStyles.margin,
padding: _responsiveUtils.isPortraitMobile(context)
padding: isPortraitMobile
? CalendarEventActionButtonWidgetStyles.paddingMobile
: CalendarEventActionButtonWidgetStyles.paddingWeb,
child: Wrap(
spacing: CalendarEventActionButtonWidgetStyles.space,
runSpacing: CalendarEventActionButtonWidgetStyles.space,
children: EventActionType.values
.validActionsOfEventMethod(eventMethod)
children: eventActions
.map((action) => AbsorbPointer(
absorbing: _getCallbackFunction(action) == null,
child: TMailButtonWidget(
@@ -58,7 +50,7 @@ class CalendarEventActionButtonWidget extends StatelessWidget {
),
textAlign: TextAlign.center,
minWidth: CalendarEventActionButtonWidgetStyles.minWidth,
width: _responsiveUtils.isPortraitMobile(context) ? double.infinity : null,
width: isPortraitMobile ? double.infinity : null,
border: Border.all(
width: CalendarEventActionButtonWidgetStyles.borderWidth,
color: _getButtonBorderColor(action)
@@ -1,7 +1,5 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/mail/calendar/calendar_event.dart';
import 'package:jmap_dart_client/jmap/mail/calendar/attendance/calendar_event_attendance.dart';
import 'package:tmail_ui_user/features/email/presentation/extensions/calendar_event_extension.dart';
@@ -16,6 +14,7 @@ import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event
import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/event_time_information_widget.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/event_title_widget.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/email_sender_builder.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/utils/app_utils.dart';
typedef OnOpenNewTabAction = void Function(String link);
@@ -33,25 +32,159 @@ class CalendarEventInformationWidget extends StatelessWidget {
final OnOpenEmailAddressDetailAction? openEmailAddressDetailAction;
final bool isFree;
final List<String> listEmailAddressSender;
final String ownEmailAddress;
final bool isPortraitMobile;
final _responsiveUtils = Get.find<ResponsiveUtils>();
CalendarEventInformationWidget({
const CalendarEventInformationWidget({
super.key,
required this.calendarEvent,
required this.onCalendarEventReplyActionClick,
required this.calendarEventReplying,
required this.isFree,
required this.ownEmailAddress,
this.onOpenNewTabAction,
this.onOpenComposerAction,
this.attendanceStatus,
this.onMailtoAttendeesAction,
this.openEmailAddressDetailAction,
this.listEmailAddressSender = const [],
this.isPortraitMobile = false,
});
@override
Widget build(BuildContext context) {
final bodyBorderRadius = isPortraitMobile
? const BorderRadiusDirectional.only(
bottomStart: CalendarEventInformationWidgetStyles.radius,
bottomEnd: CalendarEventInformationWidgetStyles.radius,
)
: const BorderRadiusDirectional.only(
topEnd: CalendarEventInformationWidgetStyles.radius,
bottomEnd: CalendarEventInformationWidgetStyles.radius,
);
final eventActionTypes = calendarEvent.getEventActionTypesIsDisplayed(
ownEmailAddress,
);
final bodyWidget = Container(
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(borderRadius: bodyBorderRadius),
color: Colors.white,
),
clipBehavior: Clip.antiAlias,
padding: const EdgeInsets.all(
CalendarEventInformationWidgetStyles.calendarInformationMargin,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (calendarEvent.organizerName.isNotEmpty)
Padding(
padding: const EdgeInsets.only(
bottom: CalendarEventInformationWidgetStyles.space,
),
child: 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: calendarEvent.getTitleEventAction(
context,
listEmailAddressSender,
),
)
],
),
),
),
if (calendarEvent.title?.isNotEmpty == true)
EventTitleWidget(title: calendarEvent.title!),
_buildEventTimeInformationWidget(),
if (calendarEvent.location?.isNotEmpty == true)
Padding(
padding: const EdgeInsets.only(
top: CalendarEventInformationWidgetStyles.fieldTopPadding,
),
child: EventLocationInformationWidget(
locationEvent: calendarEvent.location!,
onOpenComposerAction: onOpenComposerAction,
onOpenNewTabAction: onOpenNewTabAction,
),
),
if (calendarEvent.videoConferences.isNotEmpty)
Padding(
padding: const EdgeInsets.only(
top: CalendarEventDetailWidgetStyles.fieldTopPadding,
),
child: EventLinkDetailWidget(
listHyperLink: calendarEvent.videoConferences,
),
),
if (calendarEvent.participants?.isNotEmpty == true ||
calendarEvent.organizer != null)
Padding(
padding: const EdgeInsets.only(
top: CalendarEventDetailWidgetStyles.fieldTopPadding,
),
child: EventAttendeeDetailWidget(
attendees: calendarEvent.participants ?? [],
organizer: calendarEvent.organizer,
openEmailAddressDetailAction: openEmailAddressDetailAction,
),
),
if (calendarEvent.validateUserIsNotListedInParticipants(
ownEmailAddress,
))
Padding(
padding: EdgeInsetsDirectional.only(
top: CalendarEventInformationWidgetStyles.fieldTopPadding,
start: isPortraitMobile ? 0 : 100,
),
child: Text(
AppLocalizations
.of(context)
.youAreNotInvitedToThisEventPleaseContactTheOrganiser,
style: const TextStyle(
fontSize: CalendarEventInformationWidgetStyles
.invitationMessageTextSize,
fontWeight: FontWeight.w500,
color: AppColor.colorMaybeEventActionText,
),
),
),
if (eventActionTypes.isNotEmpty)
CalendarEventActionButtonWidget(
eventActions: eventActionTypes,
onCalendarEventReplyActionClick: onCalendarEventReplyActionClick,
calendarEventReplying: calendarEventReplying,
attendanceStatus: attendanceStatus,
isPortraitMobile: isPortraitMobile,
onMailToAttendeesAction: () => onMailtoAttendeesAction?.call(
calendarEvent.organizer,
calendarEvent.participants,
),
),
],
),
);
return Container(
clipBehavior: Clip.antiAlias,
decoration: const ShapeDecoration(
@@ -61,99 +194,22 @@ class CalendarEventInformationWidget extends StatelessWidget {
width: 0.5,
color: AppColor.colorCalendarEventInformationStroke,
),
borderRadius: BorderRadius.all(Radius.circular(CalendarEventInformationWidgetStyles.borderRadius)),
borderRadius: BorderRadius.all(
CalendarEventInformationWidgetStyles.radius,
),
),
),
margin: const EdgeInsetsDirectional.symmetric(
vertical: CalendarEventInformationWidgetStyles.verticalMargin,
horizontal: CalendarEventInformationWidgetStyles.horizontalMargin),
child: _responsiveUtils.isPortraitMobile(context)
child: isPortraitMobile
? Column(
children: [
CalendarDateIconWidget(
calendarEvent: calendarEvent,
width: double.infinity,
),
Container(
decoration: const ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(CalendarEventInformationWidgetStyles.borderRadius),
bottomRight: Radius.circular(CalendarEventInformationWidgetStyles.borderRadius)
)
),
color: Colors.white
),
clipBehavior: Clip.antiAlias,
padding: const EdgeInsets.all(CalendarEventInformationWidgetStyles.calendarInformationMargin),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (calendarEvent.organizerName.isNotEmpty)
Padding(
padding: const EdgeInsets.only(bottom: CalendarEventInformationWidgetStyles.space),
child: 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: calendarEvent.getTitleEventAction(context, listEmailAddressSender))
]
)
),
),
if (calendarEvent.title?.isNotEmpty == true)
EventTitleWidget(title: calendarEvent.title!),
_buildEventTimeInformationWidget(),
if (calendarEvent.location?.isNotEmpty == true)
Padding(
padding: const EdgeInsets.only(top: CalendarEventInformationWidgetStyles.fieldTopPadding),
child: EventLocationInformationWidget(
locationEvent: calendarEvent.location!,
onOpenComposerAction: onOpenComposerAction,
onOpenNewTabAction: onOpenNewTabAction,
),
),
if (calendarEvent.videoConferences.isNotEmpty)
Padding(
padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding),
child: EventLinkDetailWidget(listHyperLink: calendarEvent.videoConferences),
),
if (calendarEvent.participants?.isNotEmpty == true || calendarEvent.organizer != null)
Padding(
padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding),
child: EventAttendeeDetailWidget(
attendees: calendarEvent.participants ?? [],
organizer: calendarEvent.organizer,
openEmailAddressDetailAction: openEmailAddressDetailAction,
),
),
if (calendarEvent.isDisplayedEventReplyAction)
CalendarEventActionButtonWidget(
margin: EdgeInsetsDirectional.zero,
onCalendarEventReplyActionClick: onCalendarEventReplyActionClick,
eventMethod: calendarEvent.method,
calendarEventReplying: calendarEventReplying,
attendanceStatus: attendanceStatus,
onMailToAttendeesAction: () => onMailtoAttendeesAction?.call(
calendarEvent.organizer,
calendarEvent.participants,
),
),
],
),
)
bodyWidget,
],
)
: IntrinsicHeight(
@@ -161,86 +217,7 @@ class CalendarEventInformationWidget extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CalendarDateIconWidget(calendarEvent: calendarEvent),
Expanded(child: Container(
clipBehavior: Clip.antiAlias,
decoration: const ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
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: [
if (calendarEvent.organizerName.isNotEmpty)
Padding(
padding: const EdgeInsets.only(bottom: CalendarEventInformationWidgetStyles.space),
child: 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: calendarEvent.getTitleEventAction(context, listEmailAddressSender))
]
)
),
),
if (calendarEvent.title?.isNotEmpty == true)
EventTitleWidget(title: calendarEvent.title!),
_buildEventTimeInformationWidget(),
if (calendarEvent.location?.isNotEmpty == true)
Padding(
padding: const EdgeInsets.only(top: CalendarEventInformationWidgetStyles.fieldTopPadding),
child: EventLocationInformationWidget(
locationEvent: calendarEvent.location!,
onOpenComposerAction: onOpenComposerAction,
onOpenNewTabAction: onOpenNewTabAction,
),
),
if (calendarEvent.videoConferences.isNotEmpty)
Padding(
padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding),
child: EventLinkDetailWidget(listHyperLink: calendarEvent.videoConferences),
),
if (calendarEvent.participants?.isNotEmpty == true || calendarEvent.organizer != null)
Padding(
padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding),
child: EventAttendeeDetailWidget(
attendees: calendarEvent.participants ?? [],
organizer: calendarEvent.organizer,
openEmailAddressDetailAction: openEmailAddressDetailAction,
),
),
if (calendarEvent.isDisplayedEventReplyAction)
CalendarEventActionButtonWidget(
margin: EdgeInsetsDirectional.zero,
onCalendarEventReplyActionClick: onCalendarEventReplyActionClick,
eventMethod: calendarEvent.method,
calendarEventReplying: calendarEventReplying,
attendanceStatus: attendanceStatus,
onMailToAttendeesAction: () => onMailtoAttendeesAction?.call(
calendarEvent.organizer,
calendarEvent.participants,
),
),
],
),
))
Expanded(child: bodyWidget),
],
),
),