From 1631339ffa8c9377ebb9f7041ccc91119e680f2f Mon Sep 17 00:00:00 2001 From: Luca Date: Sun, 4 Sep 2022 15:08:41 +0200 Subject: [PATCH 1/7] WIP --- lib/provider/chat_provider.dart | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 lib/provider/chat_provider.dart diff --git a/lib/provider/chat_provider.dart b/lib/provider/chat_provider.dart new file mode 100644 index 0000000..e2166fa --- /dev/null +++ b/lib/provider/chat_provider.dart @@ -0,0 +1,28 @@ +import 'dart:collection'; + +import 'package:flutter/material.dart'; +import 'package:get_it/get_it.dart'; + +import '../model/message.dart'; +import 'auth_provider.dart'; + +typedef Uid = String; + +class ChatProvider extends ChangeNotifier { + /// Getting the instance of the AuthProvider class. + final authProvider = GetIt.I.get(); + + /// The list of messages using a [LinkedHashMap] to keep the order of the messages. + final SplayTreeSet _messages = SplayTreeSet( + (Message a, Message b) => a.time.compareTo(b.time), + ); + + /// Returning an unmodifiable list view of the messages. + get messages => UnmodifiableListView(_messages); + + /// `fetchAllMessages()` is an asynchronous function that returns a `Future` and does not take + /// any arguments + Future fetchAllMessages() async {} + + ChatProvider(); +} From 3eb10acc663c41b768812cfad2dda5d572d94809 Mon Sep 17 00:00:00 2001 From: Luca Date: Sun, 4 Sep 2022 15:32:44 +0200 Subject: [PATCH 2/7] WIP --- lib/api/imessage.dart | 6 +++--- lib/provider/chat_provider.dart | 35 +++++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/lib/api/imessage.dart b/lib/api/imessage.dart index ae071b6..1ce7c0e 100644 --- a/lib/api/imessage.dart +++ b/lib/api/imessage.dart @@ -2,8 +2,8 @@ import 'package:pdg_app/model/message.dart'; abstract class IMessage { void createMessage(Message message); - Future readMessage(String messageId); - Future?> readConversation(String firstId, String secondId); + Future readMessage(String messageId); + Future?> readConversation(String firstId, String secondId); void updateMessage(Message message); void deleteMessage(String messageId); -} \ No newline at end of file +} diff --git a/lib/provider/chat_provider.dart b/lib/provider/chat_provider.dart index e2166fa..a64621a 100644 --- a/lib/provider/chat_provider.dart +++ b/lib/provider/chat_provider.dart @@ -1,28 +1,51 @@ import 'dart:collection'; +import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; import 'package:get_it/get_it.dart'; +import 'package:pdg_app/api/firebase_message.dart'; +import '../api/firebase_user.dart'; +import '../api/imessage.dart'; +import '../api/iuser.dart'; import '../model/message.dart'; +import '../model/user.dart'; import 'auth_provider.dart'; typedef Uid = String; class ChatProvider extends ChangeNotifier { /// Getting the instance of the AuthProvider class. - final authProvider = GetIt.I.get(); + final AuthProvider _auth; + final IMessage _messageApi = FirebaseMessage(FirebaseFirestore.instance); + final IUser _userApi = FirebaseUser(FirebaseFirestore.instance); /// The list of messages using a [LinkedHashMap] to keep the order of the messages. final SplayTreeSet _messages = SplayTreeSet( (Message a, Message b) => a.time.compareTo(b.time), ); + ChatProvider(AuthProvider authProvider) : _auth = authProvider; + /// Returning an unmodifiable list view of the messages. get messages => UnmodifiableListView(_messages); - /// `fetchAllMessages()` is an asynchronous function that returns a `Future` and does not take - /// any arguments - Future fetchAllMessages() async {} - - ChatProvider(); + /// Fetching all the messages from the database. + Future fetchAllMessages() async { + List users = []; + + if (_auth.isAdmin) { + final clients = await _userApi.getDietitianClient(_auth.userUid); + users.addAll(clients); + } else { + final diet = await _userApi.readDietitianOfClient(_auth.userUid); + if (diet != null) { + users.add(diet); + } + } + + for (final user in users) { + _messageApi.readConversation(_auth.userUid, user.uid); + } + } } From f9c7e403b09492a277db34c92a2d1827d432ae89 Mon Sep 17 00:00:00 2001 From: Luca Date: Sun, 4 Sep 2022 17:13:23 +0200 Subject: [PATCH 3/7] WIP --- lib/api/firebase_message.dart | 32 ++++++++++++++++++--------- lib/provider/chat_provider.dart | 33 +++++++++++++++++++++------ lib/screens/discussion_list.dart | 35 +++++++++++++++++++++-------- lib/screens/login.dart | 4 ++-- pubspec.lock | 38 ++++++++++++++++---------------- pubspec.yaml | 1 + 6 files changed, 96 insertions(+), 47 deletions(-) diff --git a/lib/api/firebase_message.dart b/lib/api/firebase_message.dart index 2cc3eee..2f61bfc 100644 --- a/lib/api/firebase_message.dart +++ b/lib/api/firebase_message.dart @@ -42,21 +42,34 @@ class FirebaseMessage extends FirebaseAPI implements IMessage { @override Future?> readConversation( - String firstId, String secondId) async { - List userIds = [firstId, secondId]; - final querySnapshot = await collectionReference - .where('fromId', whereIn: userIds) - .where('toId', whereIn: userIds) + String userId1, String userId2) async { + final query = collectionReference + .where('fromId', isEqualTo: userId1) + .where('toId', isEqualTo: userId2) .withConverter( fromFirestore: Message.fromFirestore, toFirestore: (Message msg, _) => msg.toFirestore()) .get(); - final messages = querySnapshot.docs.map((doc) => doc.data()).toList(); + + final query2 = collectionReference + .where('fromId', isEqualTo: userId2) + .where('toId', isEqualTo: userId1) + .withConverter( + fromFirestore: Message.fromFirestore, + toFirestore: (Message msg, _) => msg.toFirestore()) + .get(); + + final querySnapshots = await Future.wait([query, query2]); + + final messages = [ + ...querySnapshots[0].docs.map((doc) => doc.data()).toList(), + ...querySnapshots[1].docs.map((doc) => doc.data()).toList(), + ]; + return messages; } - Stream followConversation( - String firstId, String secondId) { + Stream followConversation(String firstId, String secondId) { List userIds = [firstId, secondId]; final Stream msgStream = collectionReference .where('fromId', whereIn: userIds) @@ -67,8 +80,7 @@ class FirebaseMessage extends FirebaseAPI implements IMessage { .snapshots(); return msgStream - .map((querySnapshot) => - querySnapshot.docs.map((doc) => doc.data())) + .map((querySnapshot) => querySnapshot.docs.map((doc) => doc.data())) .cast(); } diff --git a/lib/provider/chat_provider.dart b/lib/provider/chat_provider.dart index a64621a..9e33421 100644 --- a/lib/provider/chat_provider.dart +++ b/lib/provider/chat_provider.dart @@ -1,9 +1,10 @@ import 'dart:collection'; +import 'dart:developer'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; -import 'package:get_it/get_it.dart'; import 'package:pdg_app/api/firebase_message.dart'; +import 'package:sorted_list/sorted_list.dart'; import '../api/firebase_user.dart'; import '../api/imessage.dart'; @@ -21,14 +22,18 @@ class ChatProvider extends ChangeNotifier { final IUser _userApi = FirebaseUser(FirebaseFirestore.instance); /// The list of messages using a [LinkedHashMap] to keep the order of the messages. - final SplayTreeSet _messages = SplayTreeSet( - (Message a, Message b) => a.time.compareTo(b.time), - ); + final Map> _messages = {}; ChatProvider(AuthProvider authProvider) : _auth = authProvider; /// Returning an unmodifiable list view of the messages. - get messages => UnmodifiableListView(_messages); + UnmodifiableListView getMessagesWith(String uid) { + final messages = _messages[uid]; + if (messages != null) { + return UnmodifiableListView(messages); + } + return UnmodifiableListView([]); + } /// Fetching all the messages from the database. Future fetchAllMessages() async { @@ -43,9 +48,23 @@ class ChatProvider extends ChangeNotifier { users.add(diet); } } - + final List?>> functions = []; for (final user in users) { - _messageApi.readConversation(_auth.userUid, user.uid); + functions.add(_messageApi.readConversation(_auth.userUid, user.uid)); + } + + final futureResult = await Future.wait(functions); + + int index = 0; + for (final conv in futureResult) { + final sortedList = + SortedList((a, b) => a.time.compareTo(b.time)); + + sortedList.addAll(conv!); + + _messages[users[index]] = sortedList; + index++; } + log(_messages.toString()); } } diff --git a/lib/screens/discussion_list.dart b/lib/screens/discussion_list.dart index d5a030a..6f5ff31 100644 --- a/lib/screens/discussion_list.dart +++ b/lib/screens/discussion_list.dart @@ -1,6 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:get_it/get_it.dart'; import 'package:pdg_app/model/custom_list_tile_data.dart'; +import 'package:provider/provider.dart'; +import '../provider/auth_provider.dart'; +import '../provider/chat_provider.dart'; import '../widgets/custom_list.dart'; class DiscussionListScreen extends StatelessWidget { @@ -8,15 +12,28 @@ class DiscussionListScreen extends StatelessWidget { @override Widget build(BuildContext context) { - return CustomList( - title: 'Discussions', - conversationsTileData: [ - CustomListTileData( - title: "test", - date: DateTime.now(), - badgeCount: 2, - ), - ], + return ChangeNotifierProvider( + create: (context) => ChatProvider(GetIt.I.get()), + builder: (context, child) { + return FutureBuilder( + future: context.read().fetchAllMessages(), + builder: (context, snapshot) => + snapshot.connectionState == ConnectionState.done + ? CustomList( + title: 'Discussions', + conversationsTileData: [ + CustomListTileData( + title: "test", + date: DateTime.now(), + badgeCount: 2, + ), + ], + ) + : Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [CircularProgressIndicator()]), + ); + }, ); } } diff --git a/lib/screens/login.dart b/lib/screens/login.dart index 2aec8f9..25bb4a2 100644 --- a/lib/screens/login.dart +++ b/lib/screens/login.dart @@ -25,8 +25,8 @@ class _LoginScreenState extends State { @override void initState() { super.initState(); - _emailController.text = "chloe.fontaine@heig-vd.ch"; - _passwordController.text = "crepes123"; + _emailController.text = "luca.coduri@heig-vd.ch"; + _passwordController.text = "crepes"; } @override diff --git a/pubspec.lock b/pubspec.lock index ec378c1..e5bb20e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -28,7 +28,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.2" + version: "2.9.0" auto_route: dependency: "direct main" description: @@ -119,14 +119,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" + version: "1.2.1" checked_yaml: dependency: transitive description: @@ -140,7 +133,7 @@ packages: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" cloud_firestore: dependency: "direct main" description: @@ -259,7 +252,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" fake_cloud_firestore: dependency: "direct dev" description: @@ -617,21 +610,21 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.11" + version: "0.12.12" material_color_utilities: dependency: transitive description: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.1.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0" mime: dependency: transitive description: @@ -659,7 +652,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" path_drawing: dependency: transitive description: @@ -826,6 +819,13 @@ packages: description: flutter source: sdk version: "0.0.99" + sorted_list: + dependency: "direct main" + description: + name: sorted_list + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" source_gen: dependency: transitive description: @@ -839,7 +839,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.9.0" stack_trace: dependency: transitive description: @@ -867,7 +867,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" table_calendar: dependency: "direct main" description: @@ -881,14 +881,14 @@ packages: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.9" + version: "0.4.12" timing: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 9a5a753..e7e0305 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -52,6 +52,7 @@ dependencies: get_it: ^7.2.0 firebase_auth_mocks: ^0.8.5+1 awesome_snackbar_content: ^0.0.8 + sorted_list: ^1.0.0 dev_dependencies: flutter_test: From e5faf58c36414a9fbf9a920707805b9e9d1a0cdd Mon Sep 17 00:00:00 2001 From: Luca Coduri Date: Mon, 5 Sep 2022 10:18:16 +0200 Subject: [PATCH 4/7] ChaListt of dietitian is working --- lib/model/custom_list_tile_data.dart | 2 + lib/model/user.dart | 9 + lib/provider/chat_provider.dart | 13 +- lib/router/chat_guard.dart | 10 +- lib/router/chat_router_page.dart | 19 ++ lib/router/router.dart | 5 +- lib/router/router.gr.dart | 318 ++++++++++++++------------- lib/screens/chat.dart | 40 +++- lib/screens/client_record.dart | 3 +- lib/screens/discussion_list.dart | 47 ++-- lib/screens/home.dart | 3 +- lib/widgets/custom_list.dart | 16 +- 12 files changed, 296 insertions(+), 189 deletions(-) create mode 100644 lib/router/chat_router_page.dart diff --git a/lib/model/custom_list_tile_data.dart b/lib/model/custom_list_tile_data.dart index 3cc84b6..84b8621 100644 --- a/lib/model/custom_list_tile_data.dart +++ b/lib/model/custom_list_tile_data.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; class CustomListTileData { final Widget? avatar; final String? title; + final String? subtitle; final DateTime? date; final int? badgeCount; final void Function()? onTap; @@ -10,6 +11,7 @@ class CustomListTileData { CustomListTileData({ this.avatar, this.title, + this.subtitle, this.date, this.badgeCount, this.onTap, diff --git a/lib/model/user.dart b/lib/model/user.dart index f69c9d4..d435d32 100644 --- a/lib/model/user.dart +++ b/lib/model/user.dart @@ -66,4 +66,13 @@ class User implements IModel { void setFirstName(String name) { firstName = name; } + + @override + bool operator ==(Object other) { + if (other is User && other.uid == uid) return true; + return false; + } + + @override + int get hashCode => Object.hash(uid, null); } diff --git a/lib/provider/chat_provider.dart b/lib/provider/chat_provider.dart index 9e33421..ebbe4de 100644 --- a/lib/provider/chat_provider.dart +++ b/lib/provider/chat_provider.dart @@ -26,8 +26,10 @@ class ChatProvider extends ChangeNotifier { ChatProvider(AuthProvider authProvider) : _auth = authProvider; + Map> get messages => UnmodifiableMapView(_messages); + /// Returning an unmodifiable list view of the messages. - UnmodifiableListView getMessagesWith(String uid) { + UnmodifiableListView getMessagesWithUid(String uid) { final messages = _messages[uid]; if (messages != null) { return UnmodifiableListView(messages); @@ -35,6 +37,15 @@ class ChatProvider extends ChangeNotifier { return UnmodifiableListView([]); } + UnmodifiableListView> getLastMessageOfEachUser() { + final result = + _messages.entries.where((element) => element.value.isNotEmpty).map((e) { + MapEntry entry = MapEntry(e.key, e.value.last); + return entry; + }).toList(); + return UnmodifiableListView(result); + } + /// Fetching all the messages from the database. Future fetchAllMessages() async { List users = []; diff --git a/lib/router/chat_guard.dart b/lib/router/chat_guard.dart index d7a32af..1c99856 100644 --- a/lib/router/chat_guard.dart +++ b/lib/router/chat_guard.dart @@ -1,8 +1,10 @@ import 'package:auto_route/auto_route.dart'; import 'package:get_it/get_it.dart'; import 'package:pdg_app/router/router.gr.dart'; +import 'package:provider/provider.dart'; import '../provider/auth_provider.dart'; +import '../provider/chat_provider.dart'; class ChatGuard extends AutoRouteGuard { @override @@ -13,7 +15,13 @@ class ChatGuard extends AutoRouteGuard { if (isAdmin) { resolver.next(true); } else { - router.push(const ChatScreenRoute()); + router.push(ChatScreenRoute( + otherUser: router.navigatorKey.currentContext! + .read() + .messages + .keys + .first, + )); } } } diff --git a/lib/router/chat_router_page.dart b/lib/router/chat_router_page.dart new file mode 100644 index 0000000..dca63e1 --- /dev/null +++ b/lib/router/chat_router_page.dart @@ -0,0 +1,19 @@ +import 'package:auto_route/annotations.dart'; +import 'package:auto_route/auto_route.dart'; +import 'package:flutter/material.dart'; +import 'package:get_it/get_it.dart'; +import 'package:pdg_app/provider/auth_provider.dart'; +import 'package:pdg_app/provider/chat_provider.dart'; +import 'package:provider/provider.dart'; + +class ChatRouterPage extends StatelessWidget { + const ChatRouterPage({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return ChangeNotifierProvider( + create: (context) => ChatProvider(GetIt.I.get()), + child: const AutoRouter(), + ); + } +} diff --git a/lib/router/router.dart b/lib/router/router.dart index fad5f73..e481730 100644 --- a/lib/router/router.dart +++ b/lib/router/router.dart @@ -2,6 +2,7 @@ import 'package:auto_route/auto_route.dart'; import 'package:auto_route/empty_router_widgets.dart'; import 'package:pdg_app/model/aftercare.dart'; import 'package:pdg_app/router/chat_guard.dart'; +import 'package:pdg_app/router/router.gr.dart'; import 'package:pdg_app/screens/add_meal.dart'; import 'package:pdg_app/screens/chat.dart'; import 'package:pdg_app/screens/client_list.dart'; @@ -20,6 +21,7 @@ import '../screens/home.dart'; import '../widgets/register/register_third_page.dart'; import '../screens/update_client_record.dart'; import './auth_gard.dart'; +import 'chat_router_page.dart'; import 'home_guard.dart'; @MaterialAutoRouter( @@ -32,8 +34,7 @@ import 'home_guard.dart'; initial: true, children: [ AutoRoute( - page: EmptyRouterPage, - name: 'ChatRouterPage', + page: ChatRouterPage, path: 'chat', children: [ AutoRoute( diff --git a/lib/router/router.gr.dart b/lib/router/router.gr.dart index 55f8821..e0b8571 100644 --- a/lib/router/router.gr.dart +++ b/lib/router/router.gr.dart @@ -11,222 +11,225 @@ // ignore_for_file: type=lint // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'package:auto_route/auto_route.dart' as _i17; -import 'package:auto_route/empty_router_widgets.dart' as _i4; -import 'package:flutter/material.dart' as _i18; - -import '../model/aftercare.dart' as _i22; -import '../model/meal.dart' as _i23; -import '../model/user.dart' as _i24; -import '../screens/add_meal.dart' as _i13; -import '../screens/chat.dart' as _i6; -import '../screens/client_list.dart' as _i9; -import '../screens/client_record.dart' as _i10; -import '../screens/diary.dart' as _i12; -import '../screens/discussion_list.dart' as _i7; -import '../screens/document_list.dart' as _i8; +import 'package:auto_route/auto_route.dart' as _i18; +import 'package:auto_route/empty_router_widgets.dart' as _i5; +import 'package:flutter/material.dart' as _i19; + +import '../model/aftercare.dart' as _i23; +import '../model/meal.dart' as _i24; +import '../model/user.dart' as _i25; +import '../screens/add_meal.dart' as _i14; +import '../screens/chat.dart' as _i7; +import '../screens/client_list.dart' as _i10; +import '../screens/client_record.dart' as _i11; +import '../screens/diary.dart' as _i13; +import '../screens/discussion_list.dart' as _i8; +import '../screens/document_list.dart' as _i9; import '../screens/home.dart' as _i1; import '../screens/login.dart' as _i2; -import '../screens/profile.dart' as _i5; +import '../screens/profile.dart' as _i6; import '../screens/register.dart' as _i3; -import '../screens/update_client_record.dart' as _i11; -import '../widgets/register/register_first_page.dart' as _i14; -import '../widgets/register/register_second_page.dart' as _i15; -import '../widgets/register/register_third_page.dart' as _i16; -import 'auth_gard.dart' as _i19; -import 'chat_guard.dart' as _i20; -import 'home_guard.dart' as _i21; - -class AppRouter extends _i17.RootStackRouter { +import '../screens/update_client_record.dart' as _i12; +import '../widgets/register/register_first_page.dart' as _i15; +import '../widgets/register/register_second_page.dart' as _i16; +import '../widgets/register/register_third_page.dart' as _i17; +import 'auth_gard.dart' as _i20; +import 'chat_guard.dart' as _i21; +import 'chat_router_page.dart' as _i4; +import 'home_guard.dart' as _i22; + +class AppRouter extends _i18.RootStackRouter { AppRouter( - {_i18.GlobalKey<_i18.NavigatorState>? navigatorKey, + {_i19.GlobalKey<_i19.NavigatorState>? navigatorKey, required this.authGuard, required this.chatGuard, required this.homeGuard}) : super(navigatorKey); - final _i19.AuthGuard authGuard; + final _i20.AuthGuard authGuard; - final _i20.ChatGuard chatGuard; + final _i21.ChatGuard chatGuard; - final _i21.HomeGuard homeGuard; + final _i22.HomeGuard homeGuard; @override - final Map pagesMap = { + final Map pagesMap = { HomeScreenRoute.name: (routeData) { - return _i17.MaterialPageX( + return _i18.MaterialPageX( routeData: routeData, child: const _i1.HomeScreen()); }, LoginScreenRoute.name: (routeData) { - return _i17.MaterialPageX( + return _i18.MaterialPageX( routeData: routeData, child: const _i2.LoginScreen()); }, RegisterScreenRoute.name: (routeData) { - return _i17.MaterialPageX( + return _i18.MaterialPageX( routeData: routeData, child: const _i3.RegisterScreen()); }, - ChatRouterPage.name: (routeData) { - return _i17.MaterialPageX( - routeData: routeData, child: const _i4.EmptyRouterPage()); + ChatRouterPageRoute.name: (routeData) { + return _i18.MaterialPageX( + routeData: routeData, child: const _i4.ChatRouterPage()); }, MainRouterPage.name: (routeData) { - return _i17.MaterialPageX( - routeData: routeData, child: const _i4.EmptyRouterPage()); + return _i18.MaterialPageX( + routeData: routeData, child: const _i5.EmptyRouterPage()); }, ProfileScreenRoute.name: (routeData) { - return _i17.MaterialPageX( - routeData: routeData, child: const _i5.ProfileScreen()); + return _i18.MaterialPageX( + routeData: routeData, child: const _i6.ProfileScreen()); }, ChatScreenRoute.name: (routeData) { - return _i17.MaterialPageX( - routeData: routeData, child: const _i6.ChatScreen()); + final args = routeData.argsAs(); + return _i18.MaterialPageX( + routeData: routeData, + child: _i7.ChatScreen(key: args.key, otherUser: args.otherUser)); }, DiscussionListScreenRoute.name: (routeData) { - return _i17.MaterialPageX( - routeData: routeData, child: const _i7.DiscussionListScreen()); + return _i18.MaterialPageX( + routeData: routeData, child: const _i8.DiscussionListScreen()); }, DocumentListScreenRoute.name: (routeData) { - return _i17.MaterialPageX( - routeData: routeData, child: const _i8.DocumentListScreen()); + return _i18.MaterialPageX( + routeData: routeData, child: const _i9.DocumentListScreen()); }, ClientListRouter.name: (routeData) { - return _i17.MaterialPageX( - routeData: routeData, child: const _i4.EmptyRouterPage()); + return _i18.MaterialPageX( + routeData: routeData, child: const _i5.EmptyRouterPage()); }, DiaryRouterPage.name: (routeData) { - return _i17.MaterialPageX( - routeData: routeData, child: const _i4.EmptyRouterPage()); + return _i18.MaterialPageX( + routeData: routeData, child: const _i5.EmptyRouterPage()); }, ClientListScreenRoute.name: (routeData) { - return _i17.MaterialPageX( - routeData: routeData, child: const _i9.ClientListScreen()); + return _i18.MaterialPageX( + routeData: routeData, child: const _i10.ClientListScreen()); }, ClientRecordScreenRoute.name: (routeData) { final args = routeData.argsAs(); - return _i17.MaterialPageX( + return _i18.MaterialPageX( routeData: routeData, - child: _i10.ClientRecordScreen(user: args.user, key: args.key)); + child: _i11.ClientRecordScreen(user: args.user, key: args.key)); }, UpdateClientRecordScreenRoute.name: (routeData) { final args = routeData.argsAs(); - return _i17.MaterialPageX<_i22.Aftercare?>( + return _i18.MaterialPageX<_i23.Aftercare?>( routeData: routeData, - child: _i11.UpdateClientRecordScreen( + child: _i12.UpdateClientRecordScreen( user: args.user, aftercare: args.aftercare, key: args.key)); }, DiaryScreenRoute.name: (routeData) { - return _i17.MaterialPageX( - routeData: routeData, child: const _i12.DiaryScreen()); + return _i18.MaterialPageX( + routeData: routeData, child: const _i13.DiaryScreen()); }, AddMealScreenRoute.name: (routeData) { final args = routeData.argsAs(); - return _i17.MaterialPageX<_i23.Meal?>( + return _i18.MaterialPageX<_i24.Meal?>( routeData: routeData, - child: _i13.AddMealScreen( + child: _i14.AddMealScreen( day: args.day, meal: args.meal, key: args.key)); }, RegisterFirstPageRoute.name: (routeData) { - return _i17.MaterialPageX( - routeData: routeData, child: const _i14.RegisterFirstPage()); + return _i18.MaterialPageX( + routeData: routeData, child: const _i15.RegisterFirstPage()); }, RegisterSecondPageRoute.name: (routeData) { final args = routeData.argsAs( orElse: () => const RegisterSecondPageRouteArgs()); - return _i17.MaterialPageX( - routeData: routeData, child: _i15.RegisterSecondPage(key: args.key)); + return _i18.MaterialPageX( + routeData: routeData, child: _i16.RegisterSecondPage(key: args.key)); }, RegisterThirdPageRoute.name: (routeData) { - return _i17.MaterialPageX( - routeData: routeData, child: const _i16.RegisterThirdPage()); + return _i18.MaterialPageX( + routeData: routeData, child: const _i17.RegisterThirdPage()); } }; @override - List<_i17.RouteConfig> get routes => [ - _i17.RouteConfig('/#redirect', + List<_i18.RouteConfig> get routes => [ + _i18.RouteConfig('/#redirect', path: '/', redirectTo: '/home', fullMatch: true), - _i17.RouteConfig(HomeScreenRoute.name, path: '/home', guards: [ + _i18.RouteConfig(HomeScreenRoute.name, path: '/home', guards: [ authGuard ], children: [ - _i17.RouteConfig('#redirect', + _i18.RouteConfig('#redirect', path: '', parent: HomeScreenRoute.name, redirectTo: 'main', fullMatch: true), - _i17.RouteConfig(ChatRouterPage.name, + _i18.RouteConfig(ChatRouterPageRoute.name, path: 'chat', parent: HomeScreenRoute.name, children: [ - _i17.RouteConfig('#redirect', + _i18.RouteConfig('#redirect', path: '', - parent: ChatRouterPage.name, + parent: ChatRouterPageRoute.name, redirectTo: 'chats', fullMatch: true), - _i17.RouteConfig(ChatScreenRoute.name, - path: 'onechat', parent: ChatRouterPage.name), - _i17.RouteConfig(DiscussionListScreenRoute.name, + _i18.RouteConfig(ChatScreenRoute.name, + path: 'onechat', parent: ChatRouterPageRoute.name), + _i18.RouteConfig(DiscussionListScreenRoute.name, path: 'chats', - parent: ChatRouterPage.name, + parent: ChatRouterPageRoute.name, guards: [chatGuard]), - _i17.RouteConfig(DocumentListScreenRoute.name, - path: 'documents', parent: ChatRouterPage.name) + _i18.RouteConfig(DocumentListScreenRoute.name, + path: 'documents', parent: ChatRouterPageRoute.name) ]), - _i17.RouteConfig(MainRouterPage.name, + _i18.RouteConfig(MainRouterPage.name, path: 'main', parent: HomeScreenRoute.name, children: [ - _i17.RouteConfig('#redirect', + _i18.RouteConfig('#redirect', path: '', parent: MainRouterPage.name, redirectTo: 'clients', fullMatch: true), - _i17.RouteConfig(ClientListRouter.name, + _i18.RouteConfig(ClientListRouter.name, path: 'clients', parent: MainRouterPage.name, guards: [ homeGuard ], children: [ - _i17.RouteConfig(ClientListScreenRoute.name, + _i18.RouteConfig(ClientListScreenRoute.name, path: '', parent: ClientListRouter.name), - _i17.RouteConfig(ClientRecordScreenRoute.name, + _i18.RouteConfig(ClientRecordScreenRoute.name, path: 'record', parent: ClientListRouter.name), - _i17.RouteConfig(UpdateClientRecordScreenRoute.name, + _i18.RouteConfig(UpdateClientRecordScreenRoute.name, path: 'update', parent: ClientListRouter.name) ]), - _i17.RouteConfig(DiaryRouterPage.name, + _i18.RouteConfig(DiaryRouterPage.name, path: 'diary', parent: MainRouterPage.name, children: [ - _i17.RouteConfig(DiaryScreenRoute.name, + _i18.RouteConfig(DiaryScreenRoute.name, path: '', parent: DiaryRouterPage.name), - _i17.RouteConfig(AddMealScreenRoute.name, + _i18.RouteConfig(AddMealScreenRoute.name, path: 'add', parent: DiaryRouterPage.name) ]) ]), - _i17.RouteConfig(ProfileScreenRoute.name, + _i18.RouteConfig(ProfileScreenRoute.name, path: 'my', parent: HomeScreenRoute.name) ]), - _i17.RouteConfig(LoginScreenRoute.name, path: '/login'), - _i17.RouteConfig(RegisterScreenRoute.name, + _i18.RouteConfig(LoginScreenRoute.name, path: '/login'), + _i18.RouteConfig(RegisterScreenRoute.name, path: '/register', children: [ - _i17.RouteConfig(RegisterFirstPageRoute.name, + _i18.RouteConfig(RegisterFirstPageRoute.name, path: '', parent: RegisterScreenRoute.name), - _i17.RouteConfig(RegisterSecondPageRoute.name, + _i18.RouteConfig(RegisterSecondPageRoute.name, path: '1', parent: RegisterScreenRoute.name), - _i17.RouteConfig(RegisterThirdPageRoute.name, + _i18.RouteConfig(RegisterThirdPageRoute.name, path: '2', parent: RegisterScreenRoute.name) ]), - _i17.RouteConfig('*#redirect', + _i18.RouteConfig('*#redirect', path: '*', redirectTo: '/home/diary', fullMatch: true) ]; } /// generated route for /// [_i1.HomeScreen] -class HomeScreenRoute extends _i17.PageRouteInfo { - const HomeScreenRoute({List<_i17.PageRouteInfo>? children}) +class HomeScreenRoute extends _i18.PageRouteInfo { + const HomeScreenRoute({List<_i18.PageRouteInfo>? children}) : super(HomeScreenRoute.name, path: '/home', initialChildren: children); static const String name = 'HomeScreenRoute'; @@ -234,7 +237,7 @@ class HomeScreenRoute extends _i17.PageRouteInfo { /// generated route for /// [_i2.LoginScreen] -class LoginScreenRoute extends _i17.PageRouteInfo { +class LoginScreenRoute extends _i18.PageRouteInfo { const LoginScreenRoute() : super(LoginScreenRoute.name, path: '/login'); static const String name = 'LoginScreenRoute'; @@ -242,8 +245,8 @@ class LoginScreenRoute extends _i17.PageRouteInfo { /// generated route for /// [_i3.RegisterScreen] -class RegisterScreenRoute extends _i17.PageRouteInfo { - const RegisterScreenRoute({List<_i17.PageRouteInfo>? children}) +class RegisterScreenRoute extends _i18.PageRouteInfo { + const RegisterScreenRoute({List<_i18.PageRouteInfo>? children}) : super(RegisterScreenRoute.name, path: '/register', initialChildren: children); @@ -251,42 +254,59 @@ class RegisterScreenRoute extends _i17.PageRouteInfo { } /// generated route for -/// [_i4.EmptyRouterPage] -class ChatRouterPage extends _i17.PageRouteInfo { - const ChatRouterPage({List<_i17.PageRouteInfo>? children}) - : super(ChatRouterPage.name, path: 'chat', initialChildren: children); +/// [_i4.ChatRouterPage] +class ChatRouterPageRoute extends _i18.PageRouteInfo { + const ChatRouterPageRoute({List<_i18.PageRouteInfo>? children}) + : super(ChatRouterPageRoute.name, + path: 'chat', initialChildren: children); - static const String name = 'ChatRouterPage'; + static const String name = 'ChatRouterPageRoute'; } /// generated route for -/// [_i4.EmptyRouterPage] -class MainRouterPage extends _i17.PageRouteInfo { - const MainRouterPage({List<_i17.PageRouteInfo>? children}) +/// [_i5.EmptyRouterPage] +class MainRouterPage extends _i18.PageRouteInfo { + const MainRouterPage({List<_i18.PageRouteInfo>? children}) : super(MainRouterPage.name, path: 'main', initialChildren: children); static const String name = 'MainRouterPage'; } /// generated route for -/// [_i5.ProfileScreen] -class ProfileScreenRoute extends _i17.PageRouteInfo { +/// [_i6.ProfileScreen] +class ProfileScreenRoute extends _i18.PageRouteInfo { const ProfileScreenRoute() : super(ProfileScreenRoute.name, path: 'my'); static const String name = 'ProfileScreenRoute'; } /// generated route for -/// [_i6.ChatScreen] -class ChatScreenRoute extends _i17.PageRouteInfo { - const ChatScreenRoute() : super(ChatScreenRoute.name, path: 'onechat'); +/// [_i7.ChatScreen] +class ChatScreenRoute extends _i18.PageRouteInfo { + ChatScreenRoute({_i19.Key? key, required _i25.User otherUser}) + : super(ChatScreenRoute.name, + path: 'onechat', + args: ChatScreenRouteArgs(key: key, otherUser: otherUser)); static const String name = 'ChatScreenRoute'; } +class ChatScreenRouteArgs { + const ChatScreenRouteArgs({this.key, required this.otherUser}); + + final _i19.Key? key; + + final _i25.User otherUser; + + @override + String toString() { + return 'ChatScreenRouteArgs{key: $key, otherUser: $otherUser}'; + } +} + /// generated route for -/// [_i7.DiscussionListScreen] -class DiscussionListScreenRoute extends _i17.PageRouteInfo { +/// [_i8.DiscussionListScreen] +class DiscussionListScreenRoute extends _i18.PageRouteInfo { const DiscussionListScreenRoute() : super(DiscussionListScreenRoute.name, path: 'chats'); @@ -294,8 +314,8 @@ class DiscussionListScreenRoute extends _i17.PageRouteInfo { } /// generated route for -/// [_i8.DocumentListScreen] -class DocumentListScreenRoute extends _i17.PageRouteInfo { +/// [_i9.DocumentListScreen] +class DocumentListScreenRoute extends _i18.PageRouteInfo { const DocumentListScreenRoute() : super(DocumentListScreenRoute.name, path: 'documents'); @@ -303,9 +323,9 @@ class DocumentListScreenRoute extends _i17.PageRouteInfo { } /// generated route for -/// [_i4.EmptyRouterPage] -class ClientListRouter extends _i17.PageRouteInfo { - const ClientListRouter({List<_i17.PageRouteInfo>? children}) +/// [_i5.EmptyRouterPage] +class ClientListRouter extends _i18.PageRouteInfo { + const ClientListRouter({List<_i18.PageRouteInfo>? children}) : super(ClientListRouter.name, path: 'clients', initialChildren: children); @@ -313,27 +333,27 @@ class ClientListRouter extends _i17.PageRouteInfo { } /// generated route for -/// [_i4.EmptyRouterPage] -class DiaryRouterPage extends _i17.PageRouteInfo { - const DiaryRouterPage({List<_i17.PageRouteInfo>? children}) +/// [_i5.EmptyRouterPage] +class DiaryRouterPage extends _i18.PageRouteInfo { + const DiaryRouterPage({List<_i18.PageRouteInfo>? children}) : super(DiaryRouterPage.name, path: 'diary', initialChildren: children); static const String name = 'DiaryRouterPage'; } /// generated route for -/// [_i9.ClientListScreen] -class ClientListScreenRoute extends _i17.PageRouteInfo { +/// [_i10.ClientListScreen] +class ClientListScreenRoute extends _i18.PageRouteInfo { const ClientListScreenRoute() : super(ClientListScreenRoute.name, path: ''); static const String name = 'ClientListScreenRoute'; } /// generated route for -/// [_i10.ClientRecordScreen] +/// [_i11.ClientRecordScreen] class ClientRecordScreenRoute - extends _i17.PageRouteInfo { - ClientRecordScreenRoute({required _i24.User user, _i18.Key? key}) + extends _i18.PageRouteInfo { + ClientRecordScreenRoute({required _i25.User user, _i19.Key? key}) : super(ClientRecordScreenRoute.name, path: 'record', args: ClientRecordScreenRouteArgs(user: user, key: key)); @@ -344,9 +364,9 @@ class ClientRecordScreenRoute class ClientRecordScreenRouteArgs { const ClientRecordScreenRouteArgs({required this.user, this.key}); - final _i24.User user; + final _i25.User user; - final _i18.Key? key; + final _i19.Key? key; @override String toString() { @@ -355,11 +375,11 @@ class ClientRecordScreenRouteArgs { } /// generated route for -/// [_i11.UpdateClientRecordScreen] +/// [_i12.UpdateClientRecordScreen] class UpdateClientRecordScreenRoute - extends _i17.PageRouteInfo { + extends _i18.PageRouteInfo { UpdateClientRecordScreenRoute( - {required dynamic user, _i22.Aftercare? aftercare, _i18.Key? key}) + {required dynamic user, _i23.Aftercare? aftercare, _i19.Key? key}) : super(UpdateClientRecordScreenRoute.name, path: 'update', args: UpdateClientRecordScreenRouteArgs( @@ -374,9 +394,9 @@ class UpdateClientRecordScreenRouteArgs { final dynamic user; - final _i22.Aftercare? aftercare; + final _i23.Aftercare? aftercare; - final _i18.Key? key; + final _i19.Key? key; @override String toString() { @@ -385,17 +405,17 @@ class UpdateClientRecordScreenRouteArgs { } /// generated route for -/// [_i12.DiaryScreen] -class DiaryScreenRoute extends _i17.PageRouteInfo { +/// [_i13.DiaryScreen] +class DiaryScreenRoute extends _i18.PageRouteInfo { const DiaryScreenRoute() : super(DiaryScreenRoute.name, path: ''); static const String name = 'DiaryScreenRoute'; } /// generated route for -/// [_i13.AddMealScreen] -class AddMealScreenRoute extends _i17.PageRouteInfo { - AddMealScreenRoute({required DateTime day, _i23.Meal? meal, _i18.Key? key}) +/// [_i14.AddMealScreen] +class AddMealScreenRoute extends _i18.PageRouteInfo { + AddMealScreenRoute({required DateTime day, _i24.Meal? meal, _i19.Key? key}) : super(AddMealScreenRoute.name, path: 'add', args: AddMealScreenRouteArgs(day: day, meal: meal, key: key)); @@ -408,9 +428,9 @@ class AddMealScreenRouteArgs { final DateTime day; - final _i23.Meal? meal; + final _i24.Meal? meal; - final _i18.Key? key; + final _i19.Key? key; @override String toString() { @@ -419,18 +439,18 @@ class AddMealScreenRouteArgs { } /// generated route for -/// [_i14.RegisterFirstPage] -class RegisterFirstPageRoute extends _i17.PageRouteInfo { +/// [_i15.RegisterFirstPage] +class RegisterFirstPageRoute extends _i18.PageRouteInfo { const RegisterFirstPageRoute() : super(RegisterFirstPageRoute.name, path: ''); static const String name = 'RegisterFirstPageRoute'; } /// generated route for -/// [_i15.RegisterSecondPage] +/// [_i16.RegisterSecondPage] class RegisterSecondPageRoute - extends _i17.PageRouteInfo { - RegisterSecondPageRoute({_i18.Key? key}) + extends _i18.PageRouteInfo { + RegisterSecondPageRoute({_i19.Key? key}) : super(RegisterSecondPageRoute.name, path: '1', args: RegisterSecondPageRouteArgs(key: key)); @@ -440,7 +460,7 @@ class RegisterSecondPageRoute class RegisterSecondPageRouteArgs { const RegisterSecondPageRouteArgs({this.key}); - final _i18.Key? key; + final _i19.Key? key; @override String toString() { @@ -449,8 +469,8 @@ class RegisterSecondPageRouteArgs { } /// generated route for -/// [_i16.RegisterThirdPage] -class RegisterThirdPageRoute extends _i17.PageRouteInfo { +/// [_i17.RegisterThirdPage] +class RegisterThirdPageRoute extends _i18.PageRouteInfo { const RegisterThirdPageRoute() : super(RegisterThirdPageRoute.name, path: '2'); diff --git a/lib/screens/chat.dart b/lib/screens/chat.dart index e5c3fc0..79694a0 100644 --- a/lib/screens/chat.dart +++ b/lib/screens/chat.dart @@ -6,7 +6,13 @@ import 'package:flutter/material.dart'; // ignore: depend_on_referenced_packages import 'package:flutter_chat_types/flutter_chat_types.dart' as types; import 'package:flutter_chat_ui/flutter_chat_ui.dart'; +import 'package:get_it/get_it.dart'; import 'package:pdg_app/router/router.gr.dart'; +import 'package:provider/provider.dart'; + +import '../model/user.dart'; +import '../provider/auth_provider.dart'; +import '../provider/chat_provider.dart'; String randomString() { final random = math.Random.secure(); @@ -15,26 +21,34 @@ String randomString() { } class ChatScreen extends StatefulWidget { - const ChatScreen({Key? key}) : super(key: key); + final User _otherUser; + const ChatScreen({ + Key? key, + required User otherUser, + }) : _otherUser = otherUser, + super(key: key); @override State createState() => _ChatScreenState(); } class _ChatScreenState extends State { - final List _messages = []; - final _user = const types.User(id: '82091008-a484-4a89-ae75-a22bf8d6f3ac'); - final _user2 = const types.User(id: '82091008-a484-4a89-ae75-a22bf8d6f3af'); + final _mainUser = types.User(id: GetIt.I.get().userUid); + + @override + void initState() { + super.initState(); + } void _addMessage(types.Message message) { setState(() { - _messages.insert(0, message); + //_messages.insert(0, message); }); } void _handleSendPressed(types.PartialText message) { final textMessage = types.TextMessage( - author: _user2, + author: _mainUser, createdAt: DateTime.now().millisecondsSinceEpoch, id: randomString(), text: message.text, @@ -45,10 +59,18 @@ class _ChatScreenState extends State { @override Widget build(BuildContext context) { + final ChatProvider chatProvider = context.watch(); return ChatInterface( - name: "Nelson", - currentUser: _user, - messages: _messages, + name: '${widget._otherUser.firstName} ${widget._otherUser.lastName}', + currentUser: _mainUser, + messages: chatProvider.messages[widget._otherUser]! + .map((m) => types.TextMessage( + id: m.uid, + author: types.User(id: m.fromId), + type: types.MessageType.text, + text: m.content, + )) + .toList(), onSendPressed: _handleSendPressed, onDocumentPressed: () { AutoRouter.of(context).push(const DocumentListScreenRoute()); diff --git a/lib/screens/client_record.dart b/lib/screens/client_record.dart index 6fcf936..1a18579 100644 --- a/lib/screens/client_record.dart +++ b/lib/screens/client_record.dart @@ -146,8 +146,7 @@ class ClientRecord extends StatelessWidget { GradientButton( color1: Theme.of(context).colorScheme.tertiary, color2: Theme.of(context).colorScheme.tertiary, - onPress: (() => AutoRouter.of(context).push( - const ChatScreenRoute())), //TODO pour sélectionner bonne discussion + onPress: () {}, // TODO changer pour sélectionner le bon chat. child: const Text( "CHAT", style: TextStyle(color: Colors.white), diff --git a/lib/screens/discussion_list.dart b/lib/screens/discussion_list.dart index 6f5ff31..bb04f58 100644 --- a/lib/screens/discussion_list.dart +++ b/lib/screens/discussion_list.dart @@ -1,3 +1,4 @@ +import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:get_it/get_it.dart'; import 'package:pdg_app/model/custom_list_tile_data.dart'; @@ -5,6 +6,7 @@ import 'package:provider/provider.dart'; import '../provider/auth_provider.dart'; import '../provider/chat_provider.dart'; +import '../router/router.gr.dart'; import '../widgets/custom_list.dart'; class DiscussionListScreen extends StatelessWidget { @@ -12,28 +14,29 @@ class DiscussionListScreen extends StatelessWidget { @override Widget build(BuildContext context) { - return ChangeNotifierProvider( - create: (context) => ChatProvider(GetIt.I.get()), - builder: (context, child) { - return FutureBuilder( - future: context.read().fetchAllMessages(), - builder: (context, snapshot) => - snapshot.connectionState == ConnectionState.done - ? CustomList( - title: 'Discussions', - conversationsTileData: [ - CustomListTileData( - title: "test", - date: DateTime.now(), - badgeCount: 2, - ), - ], - ) - : Column( - mainAxisAlignment: MainAxisAlignment.center, - children: const [CircularProgressIndicator()]), - ); - }, + return FutureBuilder( + future: context.read().fetchAllMessages(), + builder: (context, snapshot) => + snapshot.connectionState == ConnectionState.done + ? CustomList( + title: 'Discussions', + conversationsTileData: context + .watch() + .getLastMessageOfEachUser() + .map((e) => CustomListTileData( + title: '${e.key.firstName} ${e.key.lastName}', + subtitle: e.value.content, + date: e.value.time, + onTap: () { + AutoRouter.of(context) + .push(ChatScreenRoute(otherUser: e.key)); + }, + )) + .toList(), + ) + : Column( + mainAxisAlignment: MainAxisAlignment.center, + children: const [CircularProgressIndicator()]), ); } } diff --git a/lib/screens/home.dart b/lib/screens/home.dart index e642019..941168f 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -2,6 +2,7 @@ import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:pdg_app/router/router.gr.dart'; +import '../router/chat_router_page.dart'; import '../widgets/navbar.dart'; class HomeScreen extends StatefulWidget { @@ -16,7 +17,7 @@ class _HomeScreenState extends State { Widget build(BuildContext context) { return AutoTabsRouter( routes: const [ - ChatRouterPage(), + ChatRouterPageRoute(), MainRouterPage(), ProfileScreenRoute(), ], diff --git a/lib/widgets/custom_list.dart b/lib/widgets/custom_list.dart index c3bac47..3a2e0df 100644 --- a/lib/widgets/custom_list.dart +++ b/lib/widgets/custom_list.dart @@ -34,7 +34,8 @@ class CustomList extends StatelessWidget { image: AssetImage('assets/images/default_user_pic.png')), title: conv.title ?? 'Conversation ${index + 1}', - subtitle: conv.date != null + subtitle: conv.subtitle ?? '', + date: conv.date != null ? format.format(conv.date!) : 'No messages yet', badgeCount: _conversationsTileData[index].badgeCount ?? 0, @@ -58,6 +59,7 @@ class CustomList extends StatelessWidget { class _CustomListTile extends StatelessWidget { final String _title; final String _subtitle; + final String? _date; final int _badgeCount; final Widget _avatar; final void Function()? _onTap; @@ -66,6 +68,7 @@ class _CustomListTile extends StatelessWidget { Key? key, required String title, required String subtitle, + String? date, required int badgeCount, required Widget avatar, void Function()? onTap, @@ -74,6 +77,7 @@ class _CustomListTile extends StatelessWidget { _badgeCount = badgeCount, _avatar = avatar, _onTap = onTap, + _date = date, super(key: key); @override @@ -84,7 +88,15 @@ class _CustomListTile extends StatelessWidget { onTap: _onTap, leading: _avatar, trailing: _badgeCount == 0 ? const SizedBox() : Badge(_badgeCount), - title: Text(_title), + title: + Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + Text(_title), + if (_date != null) + Text( + _date!, + style: const TextStyle(fontSize: 14), + ) + ]), subtitle: Text(_subtitle), ), ); From 646f8704e31d9bed4df20714e379a64619251696 Mon Sep 17 00:00:00 2001 From: Luca Coduri Date: Mon, 5 Sep 2022 10:23:27 +0200 Subject: [PATCH 5/7] lint fix --- lib/router/chat_router_page.dart | 1 - lib/router/router.dart | 1 - lib/screens/discussion_list.dart | 2 -- lib/screens/home.dart | 1 - 4 files changed, 5 deletions(-) diff --git a/lib/router/chat_router_page.dart b/lib/router/chat_router_page.dart index dca63e1..92f7ea8 100644 --- a/lib/router/chat_router_page.dart +++ b/lib/router/chat_router_page.dart @@ -1,4 +1,3 @@ -import 'package:auto_route/annotations.dart'; import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:get_it/get_it.dart'; diff --git a/lib/router/router.dart b/lib/router/router.dart index e481730..2d48003 100644 --- a/lib/router/router.dart +++ b/lib/router/router.dart @@ -2,7 +2,6 @@ import 'package:auto_route/auto_route.dart'; import 'package:auto_route/empty_router_widgets.dart'; import 'package:pdg_app/model/aftercare.dart'; import 'package:pdg_app/router/chat_guard.dart'; -import 'package:pdg_app/router/router.gr.dart'; import 'package:pdg_app/screens/add_meal.dart'; import 'package:pdg_app/screens/chat.dart'; import 'package:pdg_app/screens/client_list.dart'; diff --git a/lib/screens/discussion_list.dart b/lib/screens/discussion_list.dart index bb04f58..87ab841 100644 --- a/lib/screens/discussion_list.dart +++ b/lib/screens/discussion_list.dart @@ -1,10 +1,8 @@ import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; -import 'package:get_it/get_it.dart'; import 'package:pdg_app/model/custom_list_tile_data.dart'; import 'package:provider/provider.dart'; -import '../provider/auth_provider.dart'; import '../provider/chat_provider.dart'; import '../router/router.gr.dart'; import '../widgets/custom_list.dart'; diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 941168f..8590097 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -2,7 +2,6 @@ import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:pdg_app/router/router.gr.dart'; -import '../router/chat_router_page.dart'; import '../widgets/navbar.dart'; class HomeScreen extends StatefulWidget { From 63e85e7f9243b2f8caace57d4178351f43d1adf9 Mon Sep 17 00:00:00 2001 From: Luca Coduri Date: Mon, 5 Sep 2022 11:28:54 +0200 Subject: [PATCH 6/7] fix pr comment --- lib/router/chat_guard.dart | 8 +------ lib/router/chat_router_page.dart | 15 ++++++++++++- lib/router/router.gr.dart | 9 ++++---- lib/screens/chat.dart | 12 ++++++---- lib/screens/discussion_list.dart | 38 +++++++++++++------------------- 5 files changed, 43 insertions(+), 39 deletions(-) diff --git a/lib/router/chat_guard.dart b/lib/router/chat_guard.dart index 1c99856..083378a 100644 --- a/lib/router/chat_guard.dart +++ b/lib/router/chat_guard.dart @@ -15,13 +15,7 @@ class ChatGuard extends AutoRouteGuard { if (isAdmin) { resolver.next(true); } else { - router.push(ChatScreenRoute( - otherUser: router.navigatorKey.currentContext! - .read() - .messages - .keys - .first, - )); + router.push(ChatScreenRoute()); } } } diff --git a/lib/router/chat_router_page.dart b/lib/router/chat_router_page.dart index 92f7ea8..7b35743 100644 --- a/lib/router/chat_router_page.dart +++ b/lib/router/chat_router_page.dart @@ -12,7 +12,20 @@ class ChatRouterPage extends StatelessWidget { Widget build(BuildContext context) { return ChangeNotifierProvider( create: (context) => ChatProvider(GetIt.I.get()), - child: const AutoRouter(), + builder: (context, child) { + return FutureBuilder( + future: context.read().fetchAllMessages(), + builder: (context, snapshot) => + snapshot.connectionState == ConnectionState.done + ? const AutoRouter() + : Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: const [CircularProgressIndicator()]), + ), + ); + }, ); } } diff --git a/lib/router/router.gr.dart b/lib/router/router.gr.dart index e0b8571..295d64f 100644 --- a/lib/router/router.gr.dart +++ b/lib/router/router.gr.dart @@ -79,7 +79,8 @@ class AppRouter extends _i18.RootStackRouter { routeData: routeData, child: const _i6.ProfileScreen()); }, ChatScreenRoute.name: (routeData) { - final args = routeData.argsAs(); + final args = routeData.argsAs( + orElse: () => const ChatScreenRouteArgs()); return _i18.MaterialPageX( routeData: routeData, child: _i7.ChatScreen(key: args.key, otherUser: args.otherUser)); @@ -283,7 +284,7 @@ class ProfileScreenRoute extends _i18.PageRouteInfo { /// generated route for /// [_i7.ChatScreen] class ChatScreenRoute extends _i18.PageRouteInfo { - ChatScreenRoute({_i19.Key? key, required _i25.User otherUser}) + ChatScreenRoute({_i19.Key? key, _i25.User? otherUser}) : super(ChatScreenRoute.name, path: 'onechat', args: ChatScreenRouteArgs(key: key, otherUser: otherUser)); @@ -292,11 +293,11 @@ class ChatScreenRoute extends _i18.PageRouteInfo { } class ChatScreenRouteArgs { - const ChatScreenRouteArgs({this.key, required this.otherUser}); + const ChatScreenRouteArgs({this.key, this.otherUser}); final _i19.Key? key; - final _i25.User otherUser; + final _i25.User? otherUser; @override String toString() { diff --git a/lib/screens/chat.dart b/lib/screens/chat.dart index 79694a0..4b3dec1 100644 --- a/lib/screens/chat.dart +++ b/lib/screens/chat.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:developer'; import 'dart:math' as math; import 'package:auto_route/auto_route.dart'; @@ -21,10 +22,10 @@ String randomString() { } class ChatScreen extends StatefulWidget { - final User _otherUser; + final User? _otherUser; const ChatScreen({ Key? key, - required User otherUser, + User? otherUser, }) : _otherUser = otherUser, super(key: key); @@ -34,6 +35,7 @@ class ChatScreen extends StatefulWidget { class _ChatScreenState extends State { final _mainUser = types.User(id: GetIt.I.get().userUid); + late User _otherUser; @override void initState() { @@ -60,10 +62,12 @@ class _ChatScreenState extends State { @override Widget build(BuildContext context) { final ChatProvider chatProvider = context.watch(); + _otherUser = widget._otherUser ?? chatProvider.messages.keys.first; + log(chatProvider.messages.toString()); return ChatInterface( - name: '${widget._otherUser.firstName} ${widget._otherUser.lastName}', + name: '${_otherUser.firstName} ${_otherUser.lastName}', currentUser: _mainUser, - messages: chatProvider.messages[widget._otherUser]! + messages: chatProvider.messages[_otherUser]! .map((m) => types.TextMessage( id: m.uid, author: types.User(id: m.fromId), diff --git a/lib/screens/discussion_list.dart b/lib/screens/discussion_list.dart index 87ab841..84f8e2c 100644 --- a/lib/screens/discussion_list.dart +++ b/lib/screens/discussion_list.dart @@ -12,29 +12,21 @@ class DiscussionListScreen extends StatelessWidget { @override Widget build(BuildContext context) { - return FutureBuilder( - future: context.read().fetchAllMessages(), - builder: (context, snapshot) => - snapshot.connectionState == ConnectionState.done - ? CustomList( - title: 'Discussions', - conversationsTileData: context - .watch() - .getLastMessageOfEachUser() - .map((e) => CustomListTileData( - title: '${e.key.firstName} ${e.key.lastName}', - subtitle: e.value.content, - date: e.value.time, - onTap: () { - AutoRouter.of(context) - .push(ChatScreenRoute(otherUser: e.key)); - }, - )) - .toList(), - ) - : Column( - mainAxisAlignment: MainAxisAlignment.center, - children: const [CircularProgressIndicator()]), + return CustomList( + title: 'Discussions', + conversationsTileData: context + .watch() + .getLastMessageOfEachUser() + .map((e) => CustomListTileData( + title: '${e.key.firstName} ${e.key.lastName}', + subtitle: e.value.content, + date: e.value.time, + onTap: () { + AutoRouter.of(context) + .push(ChatScreenRoute(otherUser: e.key)); + }, + )) + .toList(), ); } } From 5eb2a09af92e2eff78a691ddfd7eb5ac3bca626c Mon Sep 17 00:00:00 2001 From: Luca Coduri Date: Mon, 5 Sep 2022 11:37:58 +0200 Subject: [PATCH 7/7] lint fix --- lib/router/chat_guard.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/router/chat_guard.dart b/lib/router/chat_guard.dart index 083378a..b446da9 100644 --- a/lib/router/chat_guard.dart +++ b/lib/router/chat_guard.dart @@ -1,10 +1,8 @@ import 'package:auto_route/auto_route.dart'; import 'package:get_it/get_it.dart'; import 'package:pdg_app/router/router.gr.dart'; -import 'package:provider/provider.dart'; import '../provider/auth_provider.dart'; -import '../provider/chat_provider.dart'; class ChatGuard extends AutoRouteGuard { @override