Skip to content

Commit

Permalink
TW-1567: Prevent show action reply/forward when message in sending/error
Browse files Browse the repository at this point in the history
  • Loading branch information
nqhhdev authored and hoangdat committed Mar 15, 2024
1 parent 2efda04 commit c197736
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 54 deletions.
17 changes: 14 additions & 3 deletions lib/pages/chat/chat.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:fluffychat/presentation/mixins/handle_clipboard_action_mixin.dar
import 'package:fluffychat/presentation/mixins/paste_image_mixin.dart';
import 'package:fluffychat/presentation/model/chat/view_event_list_ui_state.dart';
import 'package:fluffychat/utils/extension/basic_event_extension.dart';
import 'package:fluffychat/utils/extension/event_status_custom_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/filtered_timeline_extension.dart';
import 'package:fluffychat/widgets/mixins/twake_context_menu_mixin.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
Expand Down Expand Up @@ -768,6 +769,9 @@ class ChatController extends State<Chat>
}

void forwardEventsAction({Event? event}) async {
if (event != null && !event.status.isAvailableToForwardEvent) {
return;
}
if (selectedEvents.isEmpty && event != null) {
Matrix.of(context).shareContent =
event.getDisplayEvent(timeline!).formatContentForwards();
Expand Down Expand Up @@ -809,6 +813,9 @@ class ChatController extends State<Chat>
void replyAction({
Event? replyTo,
}) {
if (replyTo?.status.isAvailableToForwardEvent == false) {
return;
}
_updateReplyEvent(
event: replyTo ?? selectedEvents.first,
);
Expand Down Expand Up @@ -1331,9 +1338,12 @@ class ChatController extends State<Chat>
openingPopupMenu.toggle();
}

List<ContextMenuItemChatAction> listHorizontalActionMenuBuilder() {
List<ContextMenuItemChatAction> listHorizontalActionMenuBuilder(
Event event,
) {
final listAction = [
ChatHorizontalActionMenu.reply,
if (event.status.isAvailableToForwardEvent)
ChatHorizontalActionMenu.reply,
ChatHorizontalActionMenu.more,
];
return listAction
Expand Down Expand Up @@ -1377,7 +1387,8 @@ class ChatController extends State<Chat>
ChatContextMenuActions.select,
if (event.isCopyable) ChatContextMenuActions.copyMessage,
ChatContextMenuActions.pinChat,
ChatContextMenuActions.forward,
if (event.status.isAvailableToForwardEvent)
ChatContextMenuActions.forward,
if (PlatformInfos.isWeb && event.hasAttachment)
ChatContextMenuActions.downloadFile,
];
Expand Down
4 changes: 2 additions & 2 deletions lib/pages/chat/chat_event_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@ class ChatEventList extends StatelessWidget {
onHover: (isHover, event) =>
controller.onHover(isHover, index, event),
isHoverNotifier: controller.focusHover,
listHorizontalActionMenu:
controller.listHorizontalActionMenuBuilder(),
listHorizontalActionMenu: controller
.listHorizontalActionMenuBuilder(event),
onMenuAction: controller.handleHorizontalActionMenu,
hideKeyboardChatScreen:
controller.onHideKeyboardAndEmoji,
Expand Down
122 changes: 78 additions & 44 deletions lib/pages/chat/chat_input_row.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,51 +31,10 @@ class ChatInputRow extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: controller.selectMode
? <Widget>[
SizedBox(
height: ChatInputRowStyle.chatInputRowHeight,
child: TextButton(
onPressed: controller.forwardEventsAction,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
const Icon(Icons.keyboard_arrow_left_outlined),
Text(L10n.of(context)!.forward),
],
),
),
? [
ActionSelectModeWidget(
controller: controller,
),
controller.selectedEvents.length == 1
? controller.selectedEvents.first
.getDisplayEvent(controller.timeline!)
.status
.isSent
? SizedBox(
height: ChatInputRowStyle.chatInputRowHeight,
child: TextButton(
onPressed: controller.replyAction,
child: Row(
children: <Widget>[
Text(L10n.of(context)!.reply),
const Icon(Icons.keyboard_arrow_right),
],
),
),
)
: SizedBox(
height: ChatInputRowStyle.chatInputRowHeight,
child: TextButton(
onPressed: controller.sendAgainAction,
child: Row(
children: <Widget>[
Text(L10n.of(context)!.tryToSendAgain),
const SizedBox(width: 4),
SvgPicture.asset(ImagePaths.icSend),
],
),
),
)
: Container(),
]
: <Widget>[
if (ChatInputRowStyle.responsiveUtils.isMobileOrTablet(context))
Expand Down Expand Up @@ -172,6 +131,81 @@ class ChatInputRow extends StatelessWidget {
}
}

class ActionSelectModeWidget extends StatelessWidget {
final ChatController controller;

const ActionSelectModeWidget({
super.key,
required this.controller,
});

@override
Widget build(BuildContext context) {
return Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (controller.selectedEvents.first
.getDisplayEvent(controller.timeline!)
.status
.isSent)
SizedBox(
height: ChatInputRowStyle.chatInputRowHeight,
child: TextButton(
onPressed: controller.forwardEventsAction,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
const Icon(Icons.keyboard_arrow_left_outlined),
Text(L10n.of(context)!.forward),
],
),
),
),
if (controller.selectedEvents.length == 1) ...[
if (controller.selectedEvents.first
.getDisplayEvent(controller.timeline!)
.status
.isSent) ...[
SizedBox(
height: ChatInputRowStyle.chatInputRowHeight,
child: TextButton(
onPressed: controller.replyAction,
child: Row(
children: <Widget>[
Text(L10n.of(context)!.reply),
const Icon(Icons.keyboard_arrow_right),
],
),
),
),
] else if (controller.selectedEvents.first
.getDisplayEvent(controller.timeline!)
.status
.isError) ...[
SizedBox(
height: ChatInputRowStyle.chatInputRowHeight,
child: TextButton(
onPressed: controller.sendAgainAction,
child: Row(
children: <Widget>[
Text(L10n.of(context)!.tryToSendAgain),
const SizedBox(width: 4),
SvgPicture.asset(ImagePaths.icSend),
],
),
),
),
] else ...[
const SizedBox.shrink(),
],
],
],
),
);
}
}

class _ChatAccountPicker extends StatelessWidget {
final ChatController controller;

Expand Down
20 changes: 15 additions & 5 deletions lib/pages/chat/events/message/message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,26 @@ typedef OnMenuAction = Function(
TapDownDetails,
);

typedef OnSwipe = void Function(SwipeDirection);

typedef OnHover = void Function(bool, Event);

typedef OnSelect = void Function(Event);

typedef OnTapAvatar = void Function(Event);

typedef OnScrollToEventId = void Function(String);

class Message extends StatefulWidget {
final Event event;
final Event? previousEvent;
final Event? nextEvent;
final String? markedUnreadLocation;
final void Function(Event)? onSelect;
final void Function(Event)? onAvatarTap;
final void Function(String)? scrollToEventId;
final void Function(SwipeDirection)? onSwipe;
final void Function(bool, Event)? onHover;
final OnSelect? onSelect;
final OnTapAvatar? onAvatarTap;
final OnScrollToEventId? scrollToEventId;
final OnSwipe? onSwipe;
final OnHover? onHover;
final ValueNotifier<String?> isHoverNotifier;
final bool selected;
final Timeline timeline;
Expand Down
7 changes: 7 additions & 0 deletions lib/utils/extension/event_status_custom_extension.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import 'package:matrix/matrix.dart';

extension EventStatusCustomExtension on EventStatus {
bool get isAvailableToForwardEvent {
return !isError && !isSending;
}
}

0 comments on commit c197736

Please sign in to comment.