From bdfcb2d22ca0fcdfc6e43e67f9a8e7f77b752971 Mon Sep 17 00:00:00 2001 From: aengzu Date: Tue, 24 Sep 2024 15:06:24 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=8C=80=ED=99=94=20=EA=B8=B0=EB=A1=9D?= =?UTF-8?q?=20=EB=B3=B4=EB=9F=AC=EA=B0=80=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/data/mapper/conversation_mapper.dart | 13 ++++++ .../models/chat/conversation_response.dart | 1 + lib/data/repository/chat_repositoryImpl.dart | 28 ++++++----- lib/di/locator.dart | 4 ++ lib/domain/model/chat/conversation.dart | 4 +- lib/domain/usecase/get_chatroom_by_user.dart | 14 +++++- .../controller/myfeedbacks_viewmodel.dart | 30 +++++++++--- .../screens/mypage/view/myfeedbacks_view.dart | 46 +++++++++++++++++-- .../screens/mypage/view/mypage_view.dart | 8 ++-- 9 files changed, 119 insertions(+), 29 deletions(-) create mode 100644 lib/data/mapper/conversation_mapper.dart diff --git a/lib/data/mapper/conversation_mapper.dart b/lib/data/mapper/conversation_mapper.dart new file mode 100644 index 0000000..16f5d20 --- /dev/null +++ b/lib/data/mapper/conversation_mapper.dart @@ -0,0 +1,13 @@ +import 'package:palink_v2/data/models/chat/conversation_response.dart'; +import 'package:palink_v2/domain/model/chat/conversation.dart'; + +extension ConversationMapper on ConversationResponse { + Conversation toDomain() { + return Conversation( + conversationId: conversationId, + day: DateTime.parse(day), + userId: userId, + characterId: characterId, + ); + } +} diff --git a/lib/data/models/chat/conversation_response.dart b/lib/data/models/chat/conversation_response.dart index dda5d58..014a7ea 100644 --- a/lib/data/models/chat/conversation_response.dart +++ b/lib/data/models/chat/conversation_response.dart @@ -19,3 +19,4 @@ class ConversationResponse { factory ConversationResponse.fromJson(Map json) => _$ConversationResponseFromJson(json); Map toJson() => _$ConversationResponseToJson(this); } + diff --git a/lib/data/repository/chat_repositoryImpl.dart b/lib/data/repository/chat_repositoryImpl.dart index f6eb7bc..4720967 100644 --- a/lib/data/repository/chat_repositoryImpl.dart +++ b/lib/data/repository/chat_repositoryImpl.dart @@ -1,8 +1,8 @@ - import 'package:palink_v2/data/api/chat/chat_api.dart'; import 'package:palink_v2/data/models/chat/ai_response_response.dart'; import 'package:palink_v2/data/models/chat/conversation_request.dart'; import 'package:palink_v2/data/models/chat/conversation_response.dart'; +import 'package:palink_v2/data/models/chat/conversations_response.dart'; import 'package:palink_v2/data/models/chat/message_request.dart'; import 'package:palink_v2/data/models/chat/message_response.dart'; import 'package:palink_v2/data/models/chat/messages_response.dart'; @@ -16,12 +16,14 @@ class ChatRepositoryImpl implements ChatRepository { ChatRepositoryImpl(this.chatApi); @override - Future createConversation(ConversationRequest conversationRequest) { + Future createConversation( + ConversationRequest conversationRequest) { return chatApi.createConversation(conversationRequest); } @override - Future saveMessage(int conversationId, MessageRequest messageRequest) { + Future saveMessage( + int conversationId, MessageRequest messageRequest) { return chatApi.saveMessage(conversationId, messageRequest); } @@ -31,25 +33,29 @@ class ChatRepositoryImpl implements ChatRepository { } @override - Future fetchConversationByChatRoomId(int conversationId) { + Future fetchConversationByChatRoomId( + int conversationId) { return chatApi.getConversationById(conversationId); } @override - Future> fetchAIResponseByMessageId(int conversationId, int messageId) { + Future> fetchAIResponseByMessageId( + int conversationId, int messageId) { return chatApi.getAIResponsesByMessageId(conversationId, messageId); } @override - Future> fetchAIResponsesByConversationId(int conversationId) { + Future> fetchAIResponsesByConversationId( + int conversationId) { return chatApi.getAIResponsesByConversationId(conversationId); } @override - Future> fetchConversationsByUserId(int userId) { - throw chatApi.getConversationsByUserId(userId); + Future> fetchConversationsByUserId( + int userId) async { + ConversationsResponse response = + await chatApi.getConversationsByUserId(userId); + return response + .conversations; // ConversationsResponse에서 conversations 리스트 추출 } - - } - diff --git a/lib/di/locator.dart b/lib/di/locator.dart index 171ca4d..1a9be7a 100644 --- a/lib/di/locator.dart +++ b/lib/di/locator.dart @@ -40,6 +40,7 @@ import 'package:palink_v2/domain/usecase/generate_initial_message_usecase.dart'; import 'package:palink_v2/domain/usecase/generate_response_usecase.dart'; import 'package:palink_v2/domain/usecase/get_ai_message_usecase.dart'; import 'package:palink_v2/domain/usecase/get_ai_messages_usecase.dart'; +import 'package:palink_v2/domain/usecase/get_chatroom_by_user.dart'; import 'package:palink_v2/domain/usecase/get_random_mindset_usecase.dart'; import 'package:palink_v2/domain/usecase/get_user_info_usecase.dart'; import 'package:palink_v2/domain/usecase/save_feedback_usecase.dart'; @@ -49,6 +50,7 @@ import 'package:palink_v2/presentation/screens/auth/controller/login_view_model. import 'package:palink_v2/presentation/screens/auth/controller/signup_view_model.dart'; import 'package:palink_v2/presentation/screens/character_select/controller/character_select_viewmodel.dart'; import 'package:palink_v2/presentation/screens/chatting/controller/tip_viewmodel.dart'; +import 'package:palink_v2/presentation/screens/mypage/controller/myfeedbacks_viewmodel.dart'; import 'package:palink_v2/presentation/screens/mypage/controller/mypage_viewmodel.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../data/repository/mindset_repositoryImpl.dart'; @@ -137,6 +139,7 @@ void _setupUseCases() { getIt.registerFactory(() => GetAIMessagesUsecase()); getIt.registerFactory(() => GetAIMessageUsecase()); getIt.registerFactory(() => SaveFeedbackUseCase()); + getIt.registerFactory(() => GetChatroomByUser(getIt(), getIt())); } @@ -147,6 +150,7 @@ void _setupViewModels() { getIt.registerFactory(() => MypageViewModel(getUserInfoUseCase: getIt())); getIt.registerLazySingleton(() => CharacterSelectViewModel(fetchCharactersUsecase: getIt())); getIt.registerFactory(() => TipViewModel()); + getIt.registerFactory(() => MyfeedbacksViewmodel()); } Future _setupDatabase() async { diff --git a/lib/domain/model/chat/conversation.dart b/lib/domain/model/chat/conversation.dart index 15c848d..8df69df 100644 --- a/lib/domain/model/chat/conversation.dart +++ b/lib/domain/model/chat/conversation.dart @@ -1,7 +1,7 @@ import 'package:palink_v2/data/models/chat/conversation_response.dart'; class Conversation { - String day; + DateTime day; int userId; int characterId; int conversationId; @@ -17,7 +17,7 @@ class Conversation { factory Conversation.fromResponse(ConversationResponse response) { return Conversation( conversationId: response.conversationId, - day: response.day, + day: DateTime.parse(response.day), userId: response.userId, characterId: response.characterId, ); diff --git a/lib/domain/usecase/get_chatroom_by_user.dart b/lib/domain/usecase/get_chatroom_by_user.dart index 032f24e..5fb1a96 100644 --- a/lib/domain/usecase/get_chatroom_by_user.dart +++ b/lib/domain/usecase/get_chatroom_by_user.dart @@ -1,3 +1,5 @@ +import 'package:palink_v2/data/mapper/conversation_mapper.dart'; +import 'package:palink_v2/domain/model/chat/conversation.dart'; import 'package:palink_v2/domain/repository/chat_repository.dart'; import 'package:palink_v2/data/models/chat/conversation_response.dart'; import 'package:palink_v2/domain/repository/user_repository.dart'; @@ -8,8 +10,16 @@ class GetChatroomByUser { GetChatroomByUser(this.chatRepository, this.userRepository); - Future> execute() async { + Future> execute() async { int? userId = userRepository.getUserId(); - return await chatRepository.fetchConversationsByUserId(userId!); + + // 서버에서 받아온 ConversationResponse 데이터를 처리하기 위해 await 사용 + List response = + await chatRepository.fetchConversationsByUserId(userId!); + + // 변환 작업 수행: List -> List + List conversations = + response.map((convResp) => convResp.toDomain()).toList(); + return conversations; } } diff --git a/lib/presentation/screens/mypage/controller/myfeedbacks_viewmodel.dart b/lib/presentation/screens/mypage/controller/myfeedbacks_viewmodel.dart index 3d4a99c..d725101 100644 --- a/lib/presentation/screens/mypage/controller/myfeedbacks_viewmodel.dart +++ b/lib/presentation/screens/mypage/controller/myfeedbacks_viewmodel.dart @@ -1,10 +1,18 @@ import 'package:get/get.dart'; +import 'package:palink_v2/di/locator.dart'; +import 'package:palink_v2/domain/model/chat/conversation.dart'; import 'package:palink_v2/domain/usecase/get_chatroom_by_user.dart'; +import 'package:palink_v2/domain/model/character/character.dart'; +import 'package:palink_v2/domain/repository/character_repository.dart'; class MyfeedbacksViewmodel extends GetxController { - final GetChatroomByUser getChatroomByUser; + final GetChatroomByUser getChatroomByUser = Get.put(getIt()); + final CharacterRepository characterRepository = Get.put(getIt()); - MyfeedbacksViewmodel(this.getChatroomByUser); + List chatrooms = []; + Map characters = {}; // 캐릭터 정보 저장 + + MyfeedbacksViewmodel(); @override void onInit() { @@ -14,13 +22,21 @@ class MyfeedbacksViewmodel extends GetxController { void _loadChatRooms() async { try { - final chatroom = await getChatroomByUser.execute(); - if (chatroom != null) { - } else { - Get.snackbar('Error', 'Failed to load user data'); + var fetchedData = await getChatroomByUser.execute(); + chatrooms = fetchedData; + + // 캐릭터 ID에 해당하는 캐릭터 데이터 불러오기 + for (var conversation in chatrooms) { + var characterId = conversation.characterId; + + var character = await characterRepository.getCharacterById(characterId); + characters[characterId] = character; // 캐릭터 정보 저장 } + + update(); // UI 업데이트 } catch (e) { - Get.snackbar('Error', 'An error occurred while loading user data'); + // 에러 발생 시 처리 + Get.snackbar('Error', 'Failed to load chatrooms'); } } } diff --git a/lib/presentation/screens/mypage/view/myfeedbacks_view.dart b/lib/presentation/screens/mypage/view/myfeedbacks_view.dart index 6b38959..699ff8f 100644 --- a/lib/presentation/screens/mypage/view/myfeedbacks_view.dart +++ b/lib/presentation/screens/mypage/view/myfeedbacks_view.dart @@ -1,8 +1,12 @@ import 'package:flutter/material.dart'; +import 'package:get/get.dart'; import 'package:palink_v2/core/theme/app_fonts.dart'; -import '../../common/appbar_perferred_size.dart'; +import 'package:palink_v2/domain/model/character/character.dart'; +import 'package:palink_v2/presentation/screens/common/appbar_perferred_size.dart'; +import 'package:palink_v2/presentation/screens/mypage/controller/myfeedbacks_viewmodel.dart'; class MyfeedbacksView extends StatelessWidget { + final MyfeedbacksViewmodel viewModel = Get.put(MyfeedbacksViewmodel()); @override Widget build(BuildContext context) { @@ -10,11 +14,47 @@ class MyfeedbacksView extends StatelessWidget { backgroundColor: const Color(0xfff5f5f5), appBar: AppBar( backgroundColor: Colors.white, - title: Text('PALINK', style: textTheme().titleLarge), + title: Text('내 피드백 기록', style: textTheme().titleMedium), centerTitle: false, bottom: appBarBottomLine(), ), - body: Text('피드백들'), + body: GetBuilder( + builder: (viewModel) { + if (viewModel.chatrooms.isEmpty) { + return const Center(child: Text('피드백이 없습니다.')); + } + + return ListView.builder( + itemCount: viewModel.chatrooms.length, + itemBuilder: (context, index) { + var chatroom = viewModel.chatrooms[index]; + var character = viewModel.characters[chatroom.characterId]; + return Column( + children: [ + ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 30.0, vertical: 15.0), + tileColor: Colors.white, // 배경을 하얀색으로 설정 + leading: ClipRRect( + borderRadius: BorderRadius.circular(10), + child: Image.asset(character!.image) + ), + title: Text(character != null ? character.name : '익명', style: textTheme().titleMedium), + subtitle: Text(_formatDate(chatroom.day)), + horizontalTitleGap: 30.0, + ), + const Divider(), + ], + ); + }, + ); + }, + ), ); } + + + // 날짜 포맷팅 함수 + String _formatDate(DateTime date) { + return '${date.year}년 ${date.month}월 ${date.day}일 ${date.hour}시 ${date.minute}분'; + } } diff --git a/lib/presentation/screens/mypage/view/mypage_view.dart b/lib/presentation/screens/mypage/view/mypage_view.dart index 1a1e44e..543c483 100644 --- a/lib/presentation/screens/mypage/view/mypage_view.dart +++ b/lib/presentation/screens/mypage/view/mypage_view.dart @@ -64,14 +64,14 @@ class MypageView extends StatelessWidget { children: [ ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 5), - title: const Text('내 친구들 보러가기'), - onTap: () => _showComingSoonDialog(context), + title: const Text('지난 피드백 보러가기'), + onTap: () => Get.to(() => MyfeedbacksView()), trailing: const Icon(Icons.arrow_forward_ios), ), ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 5), - title: const Text('지난 피드백 보러가기'), - onTap: () => Get.to(() => MyfeedbacksView()), + title: const Text('내 친구들 보러가기'), + onTap: () => _showComingSoonDialog(context), trailing: const Icon(Icons.arrow_forward_ios), ), ListTile(