Skip to content

Commit

Permalink
TW-613: Update icon and title when select multi
Browse files Browse the repository at this point in the history
  • Loading branch information
nqhhdev authored and hoangdat committed Sep 22, 2023
1 parent 62b1d67 commit 1451370
Show file tree
Hide file tree
Showing 16 changed files with 293 additions and 219 deletions.
4 changes: 3 additions & 1 deletion assets/l10n/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -2732,5 +2732,7 @@
"markThisMessageAsUnRead": "Mark this message as unread",
"muteThisMessage": "Mute this message",
"unmuteThisMessage": "Unmute this message",
"read": "Read"
"read": "Read",
"unread": "Unread",
"unmute": "Unmute"
}
181 changes: 94 additions & 87 deletions lib/pages/chat_list/chat_list.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';

import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:collection/collection.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/di/global/get_it_initializer.dart';
import 'package:fluffychat/domain/model/recovery_words/recovery_words.dart';
Expand Down Expand Up @@ -71,23 +72,8 @@ class ChatListController extends State<ChatList>

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 @@ -278,39 +264,48 @@ class ChatListController extends State<ChatList>
(conversation) => conversation.roomId == roomId,
);

final Set<ConversationSelectionPresentation> temp =
final Set<ConversationSelectionPresentation>
tempConversationSelectionPresentation =
conversationSelectionNotifier.value.toSet();

if (conversation != null) {
temp.remove(conversation);
conversationSelectionNotifier.value.toSet().remove(conversation);
} else {
temp.add(
tempConversationSelectionPresentation.add(
ConversationSelectionPresentation(
roomId: roomId,
selectionType: SelectionType.selected,
),
);
}

conversationSelectionNotifier.value = temp.toList();
conversationSelectionNotifier.value =
tempConversationSelectionPresentation.toList();
}

void toggleSelectMode() {
selectModeNotifier.value =
isSelectMode ? SelectMode.normal : SelectMode.select;
clearSelection();
_clearSelectionItem();
}

void clearSelection() {
void _clearSelectionItem() {
conversationSelectionNotifier.value = [];
}

void toggleUnread() async {
void onClickClearSelection() {
if (conversationSelectionNotifier.value.isNotEmpty) {
_clearSelectionItem();
} else {
toggleSelectMode();
}
}

Future<void> toggleUnread() async {
await showFutureLoadingDialog(
context: context,
future: () async {
final markUnread = anySelectedRoomNotMarkedUnread;
final client = Matrix.of(context).client;
for (final conversation in conversationSelectionNotifier.value) {
final room = client.getRoomById(conversation.roomId)!;
if (room.markedUnread == markUnread) continue;
Expand All @@ -321,12 +316,11 @@ class ChatListController extends State<ChatList>
toggleSelectMode();
}

void toggleFavouriteRoom() async {
Future<void> toggleFavouriteRoom() async {
await showFutureLoadingDialog(
context: context,
future: () async {
final makeFavorite = anySelectedRoomNotFavorite;
final client = Matrix.of(context).client;
for (final conversation in conversationSelectionNotifier.value) {
final room = client.getRoomById(conversation.roomId)!;
if (room.isFavourite == makeFavorite) continue;
Expand All @@ -339,14 +333,13 @@ class ChatListController extends State<ChatList>
toggleSelectMode();
}

void toggleMuted() async {
Future<void> toggleMuted() async {
await showFutureLoadingDialog(
context: context,
future: () async {
final newState = anySelectedRoomNotMuted
? PushRuleState.mentionsOnly
: PushRuleState.notify;
final client = Matrix.of(context).client;
for (final conversation in conversationSelectionNotifier.value) {
final room = client.getRoomById(conversation.roomId)!;
if (room.pushRuleState == newState) continue;
Expand Down Expand Up @@ -401,7 +394,6 @@ class ChatListController extends State<ChatList>
}

Future<void> _archiveSelectedRooms() async {
final client = Matrix.of(context).client;
while (conversationSelectionNotifier.value.isNotEmpty) {
final conversation = conversationSelectionNotifier.value.first;
try {
Expand Down Expand Up @@ -483,7 +475,6 @@ class ChatListController extends State<ChatList>
bool waitForFirstSync = false;

Future<void> _waitForFirstSync() async {
final client = Matrix.of(context).client;
await client.roomsLoading;
await client.accountDataLoading;
if (client.prevBatch == null) {
Expand Down Expand Up @@ -617,15 +608,15 @@ class ChatListController extends State<ChatList>
) async {
switch (chatListBottomNavigatorBar) {
case ChatListSelectionActions.read:
toggleUnread();
await toggleUnread();
toggleSelectMode();
return;
case ChatListSelectionActions.mute:
toggleMuted();
await toggleMuted();
toggleSelectMode();
return;
case ChatListSelectionActions.pin:
toggleFavouriteRoom();
await toggleFavouriteRoom();
toggleSelectMode();
return;
case ChatListSelectionActions.more:
Expand All @@ -634,59 +625,6 @@ class ChatListController extends State<ChatList>
}
}

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,
Expand All @@ -712,8 +650,8 @@ class ChatListController extends State<ChatList>
padding: EdgeInsets.zero,
child: popupItem(
context,
_getTitleContextMenuSelection(action, room),
iconAction: _getIconContextMenuSelection(action, room),
action.getTitleContextMenuSelection(context, room),
iconAction: action.getIconContextMenuSelection(room),
onCallbackAction: () => _handleClickOnContextMenuItem(
action,
room,
Expand Down Expand Up @@ -761,6 +699,75 @@ class ChatListController extends State<ChatList>
}
}

List<ChatListSelectionActions> _getNavigationDestinations() {
return [
ChatListSelectionActions.read,
ChatListSelectionActions.mute,
ChatListSelectionActions.pin,
ChatListSelectionActions.more,
];
}

List<Widget> bottomNavigationActionsWidget({
required EdgeInsetsDirectional paddingIcon,
double? width,
double? iconSize,
}) {
return _getNavigationDestinations().map((item) {
return InkWell(
onTap: () => _onTapBottomNavigation(item),
child: SizedBox(
width: width,
child: Column(
children: [
Padding(
padding: paddingIcon,
child: Icon(
item.getIconBottomNavigation(),
size: iconSize,
color: Theme.of(context).colorScheme.primary,
),
),
Text(
_getTitleBottomNavigation(item),
style: Theme.of(context).textTheme.labelMedium?.copyWith(
color: Theme.of(context).colorScheme.primary,
),
),
],
),
),
);
}).toList();
}

String _getTitleBottomNavigation(
ChatListSelectionActions actionBottomNavigation,
) {
switch (actionBottomNavigation) {
case ChatListSelectionActions.read:
if (anySelectedRoomNotMarkedUnread) {
return L10n.of(context)!.unread;
} else {
return L10n.of(context)!.read;
}
case ChatListSelectionActions.mute:
if (anySelectedRoomNotMuted) {
return L10n.of(context)!.mute;
} else {
return L10n.of(context)!.unmute;
}
case ChatListSelectionActions.pin:
if (anySelectedRoomNotFavorite) {
return L10n.of(context)!.pin;
} else {
return L10n.of(context)!.unpin;
}
case ChatListSelectionActions.more:
return L10n.of(context)!.more;
}
}

@override
Widget build(BuildContext context) {
return ChatListView(
Expand Down
1 change: 0 additions & 1 deletion lib/pages/chat_list/chat_list_body.dart
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@ class ChatListViewBody extends StatelessWidget {
onTap: controller.isSelectMode
? () => controller.toggleSelection(rooms[index].id)
: null,
// onLongPress: () => controller.toggleSelection(rooms[i].id),
onSecondaryTap: () => controller.handleContextMenuAction(
context,
rooms[index],
Expand Down
44 changes: 4 additions & 40 deletions lib/pages/chat_list/chat_list_bottom_navigator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import 'package:flutter/material.dart';
typedef ChatListBottomNavigatorBarIcon = Function(ChatListSelectionActions);

class ChatListBottomNavigator extends StatelessWidget {
final List<Widget> bottomNavigationActionsWidget;

const ChatListBottomNavigator({
super.key,
required this.onTapBottomNavigation,
required this.bottomNavigationActionsWidget,
});

final ChatListBottomNavigatorBarIcon onTapBottomNavigation;

@override
Widget build(BuildContext context) {
return Container(
Expand All @@ -21,44 +21,8 @@ class ChatListBottomNavigator extends StatelessWidget {
color: Theme.of(context).colorScheme.surface,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: _getNavigationDestinations.map(
(item) {
return InkWell(
onTap: () => onTapBottomNavigation(item),
child: SizedBox(
width: ChatListBottomNavigatorStyle.width,
child: Column(
children: [
Padding(
padding: ChatListBottomNavigatorStyle.paddingIcon,
child: Icon(
item.getIcon(context),
size: ChatListBottomNavigatorStyle.iconSize,
color: Theme.of(context).colorScheme.primary,
),
),
Text(
item.getTitleForMobile(context),
style: Theme.of(context).textTheme.labelMedium?.copyWith(
color: Theme.of(context).colorScheme.primary,
),
),
],
),
),
);
},
).toList(),
children: bottomNavigationActionsWidget,
),
);
}

List<ChatListSelectionActions> get _getNavigationDestinations {
return [
ChatListSelectionActions.read,
ChatListSelectionActions.mute,
ChatListSelectionActions.pin,
ChatListSelectionActions.more,
];
}
}
2 changes: 1 addition & 1 deletion lib/pages/chat_list/chat_list_header.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class ChatListHeader extends StatelessWidget {
enabled: false,
decoration: InputDecoration(
filled: true,
contentPadding: EdgeInsetsDirectional.zero,
contentPadding: ChatListHeaderStyle.paddingZero,
fillColor: Theme.of(context).colorScheme.surface,
border: OutlineInputBorder(
borderSide: BorderSide.none,
Expand Down
2 changes: 2 additions & 0 deletions lib/pages/chat_list/chat_list_header_style.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ class ChatListHeaderStyle {
start: 16,
end: 16,
);

static const EdgeInsetsDirectional paddingZero = EdgeInsetsDirectional.zero;
}
Loading

0 comments on commit 1451370

Please sign in to comment.