Skip to content

Commit

Permalink
TW-1358: Add Slidable Chat List Item - Pin/Unpin
Browse files Browse the repository at this point in the history
  • Loading branch information
Julian KOUNE committed Jan 24, 2024
1 parent b2f2ff1 commit 3491eba
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 41 deletions.
144 changes: 105 additions & 39 deletions lib/pages/chat_list/chat_list_view_builder.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import 'package:fluffychat/pages/chat_list/chat_list.dart';
import 'package:fluffychat/pages/chat_list/chat_list_item.dart';
import 'package:collection/collection.dart';
import 'package:fluffychat/pages/chat_list/chat_list_view_style.dart';
import 'package:fluffychat/presentation/enum/chat_list/chat_list_enum.dart';
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:matrix/matrix.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';

class ChatListViewBuilder extends StatelessWidget {
final ChatListController controller;
Expand All @@ -21,49 +25,111 @@ class ChatListViewBuilder extends StatelessWidget {
physics: const NeverScrollableScrollPhysics(),
itemCount: rooms.length,
itemBuilder: (BuildContext context, int index) {
return ValueListenableBuilder(
return ValueListenableBuilder<SelectMode>(
valueListenable: controller.selectModeNotifier,
builder: (context, _, __) {
return ValueListenableBuilder(
valueListenable: controller.widget.activeRoomIdNotifier,
builder: (context, activeRoomId, child) {
return ChatListItem(
rooms[index],
key: Key('chat_list_item_${rooms[index].id}'),
isEnableSelectMode: controller.isSelectMode,
onTap: controller.isSelectMode
? () => controller.toggleSelection(rooms[index].id)
: null,
onSecondaryTap: () => controller.handleContextMenuAction(
context,
rooms[index],
),
onLongPress: () => controller.onLongPressChatListItem(
rooms[index],
),
checkBoxWidget: ValueListenableBuilder(
valueListenable: controller.conversationSelectionNotifier,
builder: (context, conversationSelection, __) {
final conversation =
conversationSelection.firstWhereOrNull(
(conversation) =>
conversation.roomId.contains(rooms[index].id),
);
return Checkbox(
value: conversation?.isSelected == true,
onChanged: (_) {
controller.toggleSelection(rooms[index].id);
},
);
},
),
activeChat: activeRoomId == rooms[index].id,
);
},
);
builder: (context, selectMode, child) {
if (ChatListViewStyle.responsiveUtils.isMobileOrTablet(context) &&
!selectMode.isSelectMode) {
return _SlidableChatListItem(
controller: controller,
room: rooms[index],
chatListItem: child!,
);
}

return child!;
},
child: _CommonChatListItem(
controller: controller,
room: rooms[index],
),
);
},
);
}
}

class _CommonChatListItem extends StatelessWidget {
const _CommonChatListItem({
required this.controller,
required this.room,
});

final ChatListController controller;
final Room room;

@override
Widget build(BuildContext context) {
return ValueListenableBuilder(
valueListenable: controller.widget.activeRoomIdNotifier,
builder: (context, activeRoomId, child) {
return ChatListItem(
room,
key: Key('chat_list_item_${room.id}'),
isEnableSelectMode: controller.isSelectMode,
onTap: controller.isSelectMode
? () => controller.toggleSelection(room.id)
: null,
onSecondaryTap: () => controller.handleContextMenuAction(
context,
room,
),
onLongPress: () => controller.onLongPressChatListItem(
room,
),
checkBoxWidget: ValueListenableBuilder(
valueListenable: controller.conversationSelectionNotifier,
builder: (context, conversationSelection, __) {
final conversation = conversationSelection.firstWhereOrNull(
(conversation) => conversation.roomId.contains(room.id),
);
return Checkbox(
value: conversation?.isSelected == true,
onChanged: (_) {
controller.toggleSelection(room.id);
},
);
},
),
activeChat: activeRoomId == room.id,
);
},
);
}
}

class _SlidableChatListItem extends StatelessWidget {
const _SlidableChatListItem({
required this.controller,
required this.room,
required this.chatListItem,
});

final ChatListController controller;
final Room room;
final Widget chatListItem;

@override
Widget build(BuildContext context) {
return Slidable(
endActionPane: ActionPane(
motion: const ScrollMotion(),
extentRatio: ChatListViewStyle.slidableExtentRatio,
children: [
SlidableAction(
autoClose: true,
label: room.isFavourite
? L10n.of(context)!.unpin
: L10n.of(context)!.pin,
icon: room.isFavourite ? Icons.push_pin_outlined : Icons.push_pin,
onPressed: (_) => controller.togglePin(room),
foregroundColor: ChatListViewStyle.slidableForegroundColorDefault,
backgroundColor: Colors.greenAccent[700] ??
ChatListViewStyle.pinSlidableColorRaw,
),
],
),
child: chatListItem,
);
}
}
11 changes: 10 additions & 1 deletion lib/pages/chat_list/chat_list_view_style.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import 'package:flutter/cupertino.dart';
import 'package:fluffychat/di/global/get_it_initializer.dart';
import 'package:fluffychat/utils/responsive/responsive_utils.dart';
import 'package:flutter/material.dart';

class ChatListViewStyle {
static final responsiveUtils = getIt.get<ResponsiveUtils>();

static const editIconSize = 18.0;

static Size preferredSizeAppBar(BuildContext context) =>
const Size.fromHeight(120);

// Between 0 and 1, scale on actions length
static const double slidableExtentRatio = 0.25;
static const Color slidableForegroundColorDefault = Colors.white;
static const Color pinSlidableColorRaw = Color(0xFF00C853);
}
4 changes: 3 additions & 1 deletion lib/presentation/enum/chat_list/chat_list_enum.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import 'package:matrix/matrix.dart';

enum SelectMode {
normal,
select,
select;

bool get isSelectMode => this == SelectMode.select;
}

enum PopupMenuAction {
Expand Down
8 changes: 8 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,14 @@ packages:
url: "https://gitlab.com/TheOneWithTheBraid/flutter_secure_storage_windows.git"
source: git
version: "1.1.2"
flutter_slidable:
dependency: "direct main"
description:
name: flutter_slidable
sha256: "19ed4813003a6ff4e9c6bcce37e792a2a358919d7603b2b31ff200229191e44c"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
flutter_svg:
dependency: "direct main"
description:
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ dependencies:
flutter_localized_locales: ^2.0.5
after_layout: ^1.2.0
photo_manager_image_provider: ^2.1.0
flutter_slidable: ^3.0.1

dev_dependencies:
build_runner: ^2.3.3
Expand Down

0 comments on commit 3491eba

Please sign in to comment.