Skip to content

Commit

Permalink
TW-613: Apply new selection context menu for web
Browse files Browse the repository at this point in the history
  • Loading branch information
nqhhdev authored and hoangdat committed Sep 22, 2023
1 parent 03de4e7 commit 62b1d67
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 40 deletions.
10 changes: 8 additions & 2 deletions assets/l10n/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -2696,7 +2696,8 @@
"askToInvite": " wants you to join this chat. What do you say?",
"select" : "Select",
"copyMessageText" : "Copy message text",
"pinMessage" : "Pin message",
"pinThisMessage" : "Pin this message",
"unpinThisMessage" : "Unpin this message",
"add": "Add",
"addMembers": "Add members",
"chatInfo": "Chat info",
Expand Down Expand Up @@ -2726,5 +2727,10 @@
"errorPageDescription": "That page doesn't exist.",
"errorPageButton": "Back to chat",
"playVideo": "Play",
"done": "Done"
"done": "Done",
"markThisMessageAsRead": "Mark this message as read",
"markThisMessageAsUnRead": "Mark this message as unread",
"muteThisMessage": "Mute this message",
"unmuteThisMessage": "Unmute this message",
"read": "Read"
}
175 changes: 167 additions & 8 deletions lib/pages/chat_list/chat_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@ import 'package:fluffychat/pages/chat_list/receive_sharing_intent_mixin.dart';
import 'package:fluffychat/pages/settings_security/settings_security.dart';
import 'package:fluffychat/presentation/enum/chat_list/chat_list_enum.dart';
import 'package:fluffychat/presentation/model/chat_list/chat_selection_actions.dart';
import 'package:fluffychat/utils/extension/build_context_extension.dart';
import 'package:fluffychat/utils/famedlysdk_store.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/client_stories_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/responsive/responsive_utils.dart';
import 'package:fluffychat/utils/tor_stub.dart'
if (dart.library.html) 'package:tor_detector_web/tor_detector_web.dart';
import 'package:fluffychat/widgets/mixins/popup_context_menu_action_mixin.dart';
import 'package:fluffychat/widgets/mixins/popup_menu_widget_mixin.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
Expand Down Expand Up @@ -56,13 +60,34 @@ class ChatListController extends State<ChatList>
TickerProviderStateMixin,
RouteAware,
ComparablePresentationContactMixin,
PopupContextMenuActionMixin,
PopupMenuWidgetMixin,
ReceiveSharingIntentMixin {
final _getRecoveryWordsInteractor = getIt.get<GetRecoveryWordsInteractor>();

bool get displayNavigationBar => false;

final responsive = getIt.get<ResponsiveUtils>();

String? activeSpaceId;

late final profileMemoizers = <Client?, AsyncMemoizer<Profile>>{};

Client get client => Matrix.of(context).client;

Future<Profile?> fetchOwnProfile({required Client client}) {
if (!profileMemoizers.containsKey(client)) {
profileMemoizers[client] = AsyncMemoizer();
}
return profileMemoizers[client]!.runOnce(() async {
return await client.fetchOwnProfile();
});
}

void updateProfile(Client? client) {
profileMemoizers[client] = AsyncMemoizer<Profile>();
}

void resetActiveSpaceId() {
setState(() {
activeSpaceId = null;
Expand Down Expand Up @@ -588,16 +613,150 @@ class ChatListController extends State<ChatList>
}

void _onTapBottomNavigation(
ChatListBottomNavigatorBar chatListBottomNavigatorBar,
ChatListSelectionActions chatListBottomNavigatorBar,
) async {
switch (chatListBottomNavigatorBar) {
case ChatListBottomNavigatorBar.read:
return toggleUnread();
case ChatListBottomNavigatorBar.mute:
return toggleMuted();
case ChatListBottomNavigatorBar.pin:
return toggleFavouriteRoom();
case ChatListBottomNavigatorBar.more:
case ChatListSelectionActions.read:
toggleUnread();
toggleSelectMode();
return;
case ChatListSelectionActions.mute:
toggleMuted();
toggleSelectMode();
return;
case ChatListSelectionActions.pin:
toggleFavouriteRoom();
toggleSelectMode();
return;
case ChatListSelectionActions.more:
toggleSelectMode();
return;
}
}

String _getTitleContextMenuSelection(
ChatListSelectionActions chatListBottomNavigatorBar,
Room room,
) {
switch (chatListBottomNavigatorBar) {
case ChatListSelectionActions.read:
if (room.markedUnread) {
return L10n.of(context)!.markThisMessageAsRead;
} else {
return L10n.of(context)!.markThisMessageAsUnRead;
}
case ChatListSelectionActions.mute:
if (room.pushRuleState == PushRuleState.notify) {
return L10n.of(context)!.muteThisMessage;
} else {
return L10n.of(context)!.unmuteThisMessage;
}
case ChatListSelectionActions.pin:
return L10n.of(context)!.pinThisMessage;
case ChatListSelectionActions.more:
return L10n.of(context)!.more;
}
}

IconData _getIconContextMenuSelection(
ChatListSelectionActions chatListBottomNavigatorBar,
Room room,
) {
switch (chatListBottomNavigatorBar) {
case ChatListSelectionActions.read:
if (room.markedUnread) {
return Icons.mark_chat_read;
} else {
return Icons.mark_chat_unread;
}
case ChatListSelectionActions.mute:
if (room.pushRuleState == PushRuleState.notify) {
return Icons.volume_off;
} else {
return Icons.volume_up;
}

case ChatListSelectionActions.pin:
if (room.isFavourite) {
return Icons.push_pin_outlined;
} else {
return Icons.push_pin;
}
case ChatListSelectionActions.more:
return Icons.more_vert;
}
}

void handleContextMenuAction(
BuildContext context,
Room room,
) {
openPopupMenuAction(
context,
context.getCurrentRelativeRectOfWidget(),
_popupMenuActionTile(context, room),
);
}

List<PopupMenuItem> _popupMenuActionTile(
BuildContext context,
Room room,
) {
final listAction = [
ChatListSelectionActions.read,
ChatListSelectionActions.pin,
ChatListSelectionActions.mute,
];
return listAction.map((action) {
return PopupMenuItem(
padding: EdgeInsets.zero,
child: popupItem(
context,
_getTitleContextMenuSelection(action, room),
iconAction: _getIconContextMenuSelection(action, room),
onCallbackAction: () => _handleClickOnContextMenuItem(
action,
room,
),
),
);
}).toList();
}

void _handleClickOnContextMenuItem(
ChatListSelectionActions action,
Room room,
) async {
switch (action) {
case ChatListSelectionActions.read:
await showFutureLoadingDialog(
context: context,
future: () async {
await client.getRoomById(room.id)!.markUnread(!room.markedUnread);
},
);
return;
case ChatListSelectionActions.pin:
await showFutureLoadingDialog(
context: context,
future: () async {
await client.getRoomById(room.id)!.setFavourite(!room.isFavourite);
},
);
return;
case ChatListSelectionActions.mute:
await showFutureLoadingDialog(
context: context,
future: () async {
await client.getRoomById(room.id)!.setPushRuleState(
room.pushRuleState == PushRuleState.notify
? PushRuleState.mentionsOnly
: PushRuleState.notify,
);
},
);
return;
case ChatListSelectionActions.more:
return;
}
}
Expand Down
11 changes: 4 additions & 7 deletions lib/pages/chat_list/chat_list_body.dart
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,10 @@ class ChatListViewBody extends StatelessWidget {
? () => controller.toggleSelection(rooms[index].id)
: null,
// onLongPress: () => controller.toggleSelection(rooms[i].id),
// conversationSelectionNotifier: ValueNotifier(
// controller.conversationSelectionNotifier.value
// .firstWhereOrNull(
// (conversation) =>
// conversation.roomId.contains(rooms[i].id),
// ),
// ),
onSecondaryTap: () => controller.handleContextMenuAction(
context,
rooms[index],
),
checkBoxWidget: ValueListenableBuilder(
valueListenable:
controller.conversationSelectionNotifier,
Expand Down
16 changes: 8 additions & 8 deletions lib/pages/chat_list/chat_list_bottom_navigator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'package:fluffychat/presentation/enum/chat_list/chat_list_enum.dart';
import 'package:fluffychat/utils/responsive/responsive_utils.dart';
import 'package:flutter/material.dart';

typedef ChatListBottomNavigatorBarIcon = Function(ChatListBottomNavigatorBar);
typedef ChatListBottomNavigatorBarIcon = Function(ChatListSelectionActions);

class ChatListBottomNavigator extends StatelessWidget {
const ChatListBottomNavigator({
Expand Down Expand Up @@ -32,13 +32,13 @@ class ChatListBottomNavigator extends StatelessWidget {
Padding(
padding: ChatListBottomNavigatorStyle.paddingIcon,
child: Icon(
item.icon(context),
item.getIcon(context),
size: ChatListBottomNavigatorStyle.iconSize,
color: Theme.of(context).colorScheme.primary,
),
),
Text(
item.title(context),
item.getTitleForMobile(context),
style: Theme.of(context).textTheme.labelMedium?.copyWith(
color: Theme.of(context).colorScheme.primary,
),
Expand All @@ -53,12 +53,12 @@ class ChatListBottomNavigator extends StatelessWidget {
);
}

List<ChatListBottomNavigatorBar> get _getNavigationDestinations {
List<ChatListSelectionActions> get _getNavigationDestinations {
return [
ChatListBottomNavigatorBar.read,
ChatListBottomNavigatorBar.mute,
ChatListBottomNavigatorBar.pin,
ChatListBottomNavigatorBar.more,
ChatListSelectionActions.read,
ChatListSelectionActions.mute,
ChatListSelectionActions.pin,
ChatListSelectionActions.more,
];
}
}
5 changes: 3 additions & 2 deletions lib/pages/chat_list/chat_list_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class ChatListItem extends StatelessWidget with ChatListItemMixin {
final Widget? checkBoxWidget;
final void Function()? onTap;
final void Function()? onLongPress;
final void Function()? onSecondaryTap;

const ChatListItem(
this.room, {
Expand All @@ -30,6 +31,7 @@ class ChatListItem extends StatelessWidget with ChatListItemMixin {
this.isEnableSelectMode = false,
this.onTap,
this.onLongPress,
this.onSecondaryTap,
Key? key,
}) : super(key: key);

Expand Down Expand Up @@ -100,8 +102,7 @@ class ChatListItem extends StatelessWidget with ChatListItemMixin {
child: InkWell(
onTap: () => clickAction(context),
// onLongPress: onLongPress,
onSecondaryTap: () {},
onDoubleTap: () {},
onSecondaryTap: onSecondaryTap,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Row(
Expand Down
38 changes: 25 additions & 13 deletions lib/presentation/enum/chat_list/chat_list_enum.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,34 +21,46 @@ enum ActiveFilter {
spaces,
}

enum ChatListBottomNavigatorBar {
enum ChatListSelectionActions {
read,
mute,
pin,
more;

String title(BuildContext context) {
String getTitleForMobile(BuildContext context) {
switch (this) {
case ChatListBottomNavigatorBar.read:
case ChatListSelectionActions.read:
return L10n.of(context)!.contacts;
case ChatListBottomNavigatorBar.mute:
case ChatListSelectionActions.mute:
return L10n.of(context)!.mute;
case ChatListBottomNavigatorBar.pin:
case ChatListSelectionActions.pin:
return L10n.of(context)!.pin;
case ChatListBottomNavigatorBar.more:
case ChatListSelectionActions.more:
return L10n.of(context)!.more;
}
}

IconData icon(BuildContext context) {
IconData getIcon(
BuildContext context, {
bool isMobile = true,
}) {
switch (this) {
case ChatListBottomNavigatorBar.read:
return Icons.mark_email_read;
case ChatListBottomNavigatorBar.mute:
return Icons.notifications_off;
case ChatListBottomNavigatorBar.pin:
case ChatListSelectionActions.read:
if (isMobile) {
return Icons.mark_email_read;
} else {
return Icons.mark_chat_read;
}
case ChatListSelectionActions.mute:
if (isMobile) {
return Icons.notifications_off;
} else {
return Icons.volume_off;
}

case ChatListSelectionActions.pin:
return Icons.push_pin;
case ChatListBottomNavigatorBar.more:
case ChatListSelectionActions.more:
return Icons.more_vert;
}
}
Expand Down

0 comments on commit 62b1d67

Please sign in to comment.