diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 092a971..97fd8f4 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1256,4 +1256,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: f6f9d8c752193d83788e2c1ea9d68279decb9a93 -COCOAPODS: 1.12.1 +COCOAPODS: 1.15.2 diff --git a/lib/_shared/bloc/user_manager/user_manager_cubit.dart b/lib/_shared/bloc/user_manager/user_manager_cubit.dart deleted file mode 100644 index a57d10c..0000000 --- a/lib/_shared/bloc/user_manager/user_manager_cubit.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:equatable/equatable.dart'; -import 'package:public_chat/_shared/data/chat_data.dart'; -import 'package:public_chat/repository/database.dart'; -import 'package:public_chat/service_locator/service_locator.dart'; -import 'package:public_chat/utils/bloc_extensions.dart'; - -part 'user_manager_state.dart'; - -class UserManagerCubit extends Cubit { - UserManagerCubit() : super(UserManagerInitial()); - - void queryUserDetail(String uid) async { - final DocumentSnapshot userDetail = - await ServiceLocator.instance.get().getUser(uid); - emitSafely( - UserDetailState( - uid: uid, - photoUrl: userDetail.data()?.photoUrl, - displayName: userDetail.data()?.displayName, - ), - ); - } -} diff --git a/lib/_shared/bloc/user_manager/user_manager_state.dart b/lib/_shared/bloc/user_manager/user_manager_state.dart deleted file mode 100644 index 3b5ee6a..0000000 --- a/lib/_shared/bloc/user_manager/user_manager_state.dart +++ /dev/null @@ -1,22 +0,0 @@ -part of 'user_manager_cubit.dart'; - -abstract class UserManagerState extends Equatable { - const UserManagerState(); -} - -class UserManagerInitial extends UserManagerState { - @override - List get props => []; -} - -final class UserDetailState extends UserManagerState { - final String uid; - final String? photoUrl; - final String? displayName; - - const UserDetailState( - {required this.uid, required this.photoUrl, required this.displayName}); - - @override - List get props => [uid, photoUrl, displayName]; -} diff --git a/lib/_shared/data/chat_data.dart b/lib/_shared/data/chat_data.dart index 37d1ddd..cd8bc4b 100644 --- a/lib/_shared/data/chat_data.dart +++ b/lib/_shared/data/chat_data.dart @@ -3,21 +3,34 @@ import 'package:firebase_auth/firebase_auth.dart'; final class Message { final String id; - final String sender; + final String senderId; + final String senderDisplayName; + final String? senderPhotoUrl; final Timestamp timestamp; final Map translations; - Message({required this.sender, required this.translations}) - : id = '', + Message({ + required this.senderId, + required this.senderDisplayName, + required this.senderPhotoUrl, + required this.translations, + }) : id = '', timestamp = Timestamp.now(); Message.fromMap(this.id, Map map) - : sender = map['sender'], + : senderId = map['senderId'], + senderDisplayName = map['senderDisplayName'], + senderPhotoUrl = map['senderPhotoUrl'], timestamp = map['time'], translations = map['translated'] as Map? ?? {}; - Map toMap() => - {'sender': sender, 'time': timestamp, 'translated': translations}; + Map toMap() => { + 'senderId': senderId, + 'senderDisplayName': senderDisplayName, + 'senderPhotoUrl': senderPhotoUrl, + 'time': timestamp, + 'translated': translations + }; } final class UserDetail { diff --git a/lib/features/chat/bloc/chat_cubit.dart b/lib/features/chat/bloc/chat_cubit.dart index a78ff19..d32bc83 100644 --- a/lib/features/chat/bloc/chat_cubit.dart +++ b/lib/features/chat/bloc/chat_cubit.dart @@ -1,5 +1,6 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:equatable/equatable.dart'; +import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:public_chat/_shared/data/chat_data.dart'; import 'package:public_chat/repository/database.dart'; @@ -30,10 +31,12 @@ class ChatCubit extends Cubit { toFireStore: (value, options) => value.toMap(), ); - void sendChat({required String uid, required String message}) { + void sendChat({required User user, required String message}) { ServiceLocator.instance.get().writePublicMessage( Message( - sender: uid, + senderId: user.uid, + senderDisplayName: user.displayName ?? '', + senderPhotoUrl: user.photoURL, translations: {currentLanguageCodeSelected: message}, ), ); diff --git a/lib/features/chat/ui/chat_screen.dart b/lib/features/chat/ui/chat_screen.dart index da8da03..5da7002 100644 --- a/lib/features/chat/ui/chat_screen.dart +++ b/lib/features/chat/ui/chat_screen.dart @@ -5,7 +5,6 @@ import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_ui_firestore/firebase_ui_firestore.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:public_chat/_shared/bloc/user_manager/user_manager_cubit.dart'; import 'package:public_chat/_shared/data/chat_data.dart'; import 'package:public_chat/_shared/widgets/chat_bubble_widget.dart'; import 'package:public_chat/_shared/widgets/message_box_widget.dart'; @@ -55,6 +54,37 @@ class _ChatScreenState extends State { : widget.currentLanguageCode; } + void _handleActionLogoutSuccess(ChatCubit chatCubit) { + FunctionsAlertDialog.showAlertFlushBar( + context, + Helper.getTextTranslated( + 'logoutSuccessMessage', + _getCurrentLanguageCode(chatCubit), + ), + true, + ); + Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (context) => LoginScreen( + currentCountryCode: _getCurrentCountryCode(chatCubit), + currentLanguageCode: _getCurrentLanguageCode(chatCubit), + ), + ), + ); + } + + void _handleActionLogoutFailure(ChatCubit chatCubit) { + FunctionsAlertDialog.showAlertFlushBar( + context, + Helper.getTextTranslated( + 'logoutFailMessage', + _getCurrentLanguageCode(chatCubit), + ), + false, + ); + } + @override Widget build(BuildContext context) { final chatCubit = context.read(); @@ -71,33 +101,10 @@ class _ChatScreenState extends State { Navigator.of(context).pop(); } if (state is LogoutSuccess && context.mounted) { - FunctionsAlertDialog.showAlertFlushBar( - context, - Helper.getTextTranslated( - 'logoutSuccessMessage', - _getCurrentLanguageCode(chatCubit), - ), - true, - ); - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => LoginScreen( - currentCountryCode: _getCurrentCountryCode(chatCubit), - currentLanguageCode: _getCurrentLanguageCode(chatCubit), - ), - ), - ); + _handleActionLogoutSuccess(chatCubit); } if (state is LogoutFailed && context.mounted) { - FunctionsAlertDialog.showAlertFlushBar( - context, - Helper.getTextTranslated( - 'logoutFailMessage', - _getCurrentLanguageCode(chatCubit), - ), - false, - ); + _handleActionLogoutFailure(chatCubit); } }, child: Scaffold( @@ -113,16 +120,7 @@ class _ChatScreenState extends State { child: Column( children: [ _buildListMessage(chatCubit), - MessageBox( - onSendMessage: (value) { - final User? user = FirebaseAuth.instance.currentUser; - if (user == null || value.trim().isEmpty) { - // do nothing - return; - } - chatCubit.sendChat(uid: user.uid, message: value); - }, - ) + _buildMessageBox(chatCubit), ], ), ), @@ -286,30 +284,12 @@ class _ChatScreenState extends State { return const SizedBox.shrink(); } final message = doc.data(); - if (message.sender.isNotEmpty) { - context - .read() - .queryUserDetail(message.sender); - return BlocBuilder( - builder: (context, state) { - String? photoUrl; - String? displayName; - - if (state is UserDetailState) { - photoUrl = state.photoUrl; - displayName = state.displayName; - } - - return ChatBubble( - isMine: message.sender == user?.uid, - message: chatCubit.getMessageTranslated(message), - photoUrl: photoUrl, - displayName: displayName, - ); - }, - ); - } - return const SizedBox.shrink(); + return ChatBubble( + isMine: message.senderId == user?.uid, + message: chatCubit.getMessageTranslated(message), + photoUrl: message.senderPhotoUrl, + displayName: message.senderDisplayName, + ); }, emptyBuilder: (context) => Center( child: BlocBuilder( @@ -339,4 +319,17 @@ class _ChatScreenState extends State { }, ); } + + Widget _buildMessageBox(ChatCubit chatCubit) { + final User? user = FirebaseAuth.instance.currentUser; + return MessageBox( + onSendMessage: (value) { + if (user == null || value.trim().isEmpty) { + // do nothing + return; + } + chatCubit.sendChat(user: user, message: value); + }, + ); + } } diff --git a/lib/main.dart b/lib/main.dart index 80b7822..6d3babf 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,7 +4,6 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:public_chat/_shared/bloc/user_manager/user_manager_cubit.dart'; import 'package:public_chat/features/chat/chat.dart'; import 'package:public_chat/features/country/country.dart'; import 'package:public_chat/features/genai_setting/bloc/genai_bloc.dart'; @@ -31,7 +30,6 @@ class MainApp extends StatelessWidget { create: (context) => LanguageLoadCubit(), ), BlocProvider(create: (context) => LoginCubit()), - BlocProvider(create: (context) => UserManagerCubit()), BlocProvider(create: (context) => GenaiBloc()), BlocProvider(create: (context) => ChatCubit()), BlocProvider(create: (context) => CountryCubit()), diff --git a/lib/utils/app_extensions.dart b/lib/utils/app_extensions.dart index 3cb2429..76be081 100644 --- a/lib/utils/app_extensions.dart +++ b/lib/utils/app_extensions.dart @@ -6,7 +6,7 @@ import 'package:public_chat/service_locator/service_locator.dart'; extension UserPhotoUrl on Message { Future get userDetail async { final DocumentSnapshot snapshot = - await ServiceLocator.instance.get().getUser(sender); + await ServiceLocator.instance.get().getUser(senderId); if (!snapshot.exists) { return null;