chat list work

This commit is contained in:
Christien Rioux 2024-01-30 18:32:56 -05:00
parent 03a6a781a6
commit ba73123702
2 changed files with 78 additions and 89 deletions

View File

@ -1,9 +1,12 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:flutter_translate/flutter_translate.dart';
import '../../chat/cubits/active_chat_cubit.dart';
import '../../proto/proto.dart' as proto;
import '../../theme/theme.dart';
import '../chat_list.dart';
class ChatSingleContactItemWidget extends StatelessWidget {
const ChatSingleContactItemWidget({required proto.Contact contact, super.key})
@ -20,10 +23,10 @@ class ChatSingleContactItemWidget extends StatelessWidget {
//final textTheme = theme.textTheme;
final scale = theme.extension<ScaleScheme>()!;
final activeChat = ref.watch(activeChatStateProvider);
final activeChatCubit = context.watch<ActiveChatCubit>();
final remoteConversationRecordKey =
proto.TypedKeyProto.fromProto(contact.remoteConversationRecordKey);
final selected = activeChat == remoteConversationRecordKey;
proto.TypedKeyProto.fromProto(_contact.remoteConversationRecordKey);
final selected = activeChatCubit.state == remoteConversationRecordKey;
return Container(
margin: const EdgeInsets.fromLTRB(0, 4, 0, 0),
@ -34,21 +37,16 @@ class ChatSingleContactItemWidget extends StatelessWidget {
borderRadius: BorderRadius.circular(8),
)),
child: Slidable(
key: ObjectKey(contact),
key: ObjectKey(_contact),
endActionPane: ActionPane(
motion: const DrawerMotion(),
children: [
SlidableAction(
onPressed: (context) async {
final activeAccountInfo =
await ref.read(fetchActiveAccountProvider.future);
if (activeAccountInfo != null) {
await deleteChat(
activeAccountInfo: activeAccountInfo,
remoteConversationRecordKey:
remoteConversationRecordKey);
ref.invalidate(fetchChatListProvider);
}
final chatListCubit = context.read<ChatListCubit>();
await chatListCubit.deleteChat(
remoteConversationRecordKey:
remoteConversationRecordKey);
},
backgroundColor: scale.tertiaryScale.background,
foregroundColor: scale.tertiaryScale.text,
@ -68,16 +66,14 @@ class ChatSingleContactItemWidget extends StatelessWidget {
// The child of the Slidable is what the user sees when the
// component is not dragged.
child: ListTile(
onTap: () async {
ref.read(activeChatStateProvider.notifier).state =
remoteConversationRecordKey;
ref.invalidate(fetchChatListProvider);
onTap: () {
activeChatCubit.setActiveChat(remoteConversationRecordKey);
},
title: Text(contact.editedProfile.name),
title: Text(_contact.editedProfile.name),
/// xxx show last message here
subtitle: (contact.editedProfile.pronouns.isNotEmpty)
? Text(contact.editedProfile.pronouns)
subtitle: (_contact.editedProfile.pronouns.isNotEmpty)
? Text(_contact.editedProfile.pronouns)
: null,
iconColor: scale.tertiaryScale.background,
textColor: scale.tertiaryScale.text,
@ -89,6 +85,6 @@ class ChatSingleContactItemWidget extends StatelessWidget {
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<proto.Contact>('contact', contact));
properties.add(DiagnosticsProperty<proto.Contact>('contact', _contact));
}
}

View File

@ -1,92 +1,85 @@
import 'package:awesome_extensions/awesome_extensions.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_translate/flutter_translate.dart';
import 'package:searchable_listview/searchable_listview.dart';
import '../proto/proto.dart' as proto;
import '../tools/tools.dart';
import '../../contacts/contacts.dart';
import '../../proto/proto.dart' as proto;
import '../../theme/theme.dart';
import '../../tools/tools.dart';
import '../chat_list.dart';
import 'chat_single_contact_item_widget.dart';
import 'empty_chat_list_widget.dart';
class ChatSingleContactListWidget extends ConsumerWidget {
ChatSingleContactListWidget(
{required IList<proto.Contact> contactList,
required this.chatList,
super.key})
: contactMap = IMap.fromIterable(contactList,
keyMapper: (c) => c.remoteConversationRecordKey,
valueMapper: (c) => c);
final IMap<proto.TypedKey, proto.Contact> contactMap;
final IList<proto.Chat> chatList;
class ChatSingleContactListWidget extends StatelessWidget {
const ChatSingleContactListWidget({super.key});
@override
// ignore: prefer_expression_function_bodies
Widget build(BuildContext context, WidgetRef ref) {
Widget build(BuildContext context) {
final theme = Theme.of(context);
//final textTheme = theme.textTheme;
final scale = theme.extension<ScaleScheme>()!;
return SizedBox.expand(
child: styledTitleContainer(
context: context,
title: translate('chat_list.chats'),
child: SizedBox.expand(
child: (chatList.isEmpty)
? const EmptyChatListWidget()
: SearchableList<proto.Chat>(
autoFocusOnSearch: false,
initialList: chatList.toList(),
builder: (l, i, c) {
final contact =
contactMap[c.remoteConversationKey];
if (contact == null) {
return const Text('...');
}
return ChatSingleContactItemWidget(
contact: contact);
},
filter: (value) {
final lowerValue = value.toLowerCase();
return chatList.where((c) {
final contactListV = context.watch<ContactListCubit>().state;
return contactListV.builder((context, contactList) {
final contactMap = IMap.fromIterable(contactList,
keyMapper: (c) => c.remoteConversationRecordKey,
valueMapper: (c) => c);
final chatListV = context.watch<ChatListCubit>().state;
return chatListV.builder((context, chatList) => SizedBox.expand(
child: styledTitleContainer(
context: context,
title: translate('chat_list.chats'),
child: SizedBox.expand(
child: (chatList.isEmpty)
? const EmptyChatListWidget()
: SearchableList<proto.Chat>(
autoFocusOnSearch: false,
initialList: chatList.toList(),
builder: (l, i, c) {
final contact =
contactMap[c.remoteConversationKey];
if (contact == null) {
return false;
return const Text('...');
}
return contact.editedProfile.name
.toLowerCase()
.contains(lowerValue) ||
contact.editedProfile.pronouns
.toLowerCase()
.contains(lowerValue);
}).toList();
},
spaceBetweenSearchAndList: 4,
inputDecoration: InputDecoration(
labelText: translate('chat_list.search'),
contentPadding: const EdgeInsets.all(2),
fillColor: scale.primaryScale.text,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: scale.primaryScale.hoverBorder,
return ChatSingleContactItemWidget(
contact: contact);
},
filter: (value) {
final lowerValue = value.toLowerCase();
return chatList.where((c) {
final contact =
contactMap[c.remoteConversationKey];
if (contact == null) {
return false;
}
return contact.editedProfile.name
.toLowerCase()
.contains(lowerValue) ||
contact.editedProfile.pronouns
.toLowerCase()
.contains(lowerValue);
}).toList();
},
spaceBetweenSearchAndList: 4,
inputDecoration: InputDecoration(
labelText: translate('chat_list.search'),
contentPadding: const EdgeInsets.all(2),
fillColor: scale.primaryScale.text,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: scale.primaryScale.hoverBorder,
),
borderRadius: BorderRadius.circular(8),
),
borderRadius: BorderRadius.circular(8),
),
),
).paddingAll(8))))
.paddingLTRB(8, 8, 8, 65);
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties
..add(DiagnosticsProperty<IMap<proto.TypedKey, proto.Contact>>(
'contactMap', contactMap))
..add(IterableProperty<proto.Chat>('chatList', chatList));
).paddingAll(8))))
.paddingLTRB(8, 8, 8, 65));
});
}
}