Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 리액션 반응 추가 #12

Merged
merged 1 commit into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ PODS:
- device_info_plus (0.0.1):
- Flutter
- Flutter (1.0.0)
- fluttertoast (0.0.2):
- Flutter
- Toast
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
Expand All @@ -11,6 +14,7 @@ PODS:
- sqflite (0.0.3):
- Flutter
- FlutterMacOS
- Toast (4.1.1)
- url_launcher_ios (0.0.1):
- Flutter
- vibration (1.7.5):
Expand All @@ -19,17 +23,24 @@ PODS:
DEPENDENCIES:
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- Flutter (from `Flutter`)
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqflite (from `.symlinks/plugins/sqflite/darwin`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- vibration (from `.symlinks/plugins/vibration/ios`)

SPEC REPOS:
trunk:
- Toast

EXTERNAL SOURCES:
device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios"
Flutter:
:path: Flutter
fluttertoast:
:path: ".symlinks/plugins/fluttertoast/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
shared_preferences_foundation:
Expand All @@ -44,9 +55,11 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
fluttertoast: e9a18c7be5413da53898f660530c56f35edfba9c
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
vibration: 7d883d141656a1c1a6d8d238616b2042a51a1241

Expand Down
1 change: 1 addition & 0 deletions lib/data/mapper/message_response_mapper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:palink_v2/domain/entities/chat/message.dart';
extension MessageResponseMapper on MessageResponse {
Message toDomain() {
return Message(
id: messageId.toString(),
sender: sender,
messageText: messageText,
timestamp: timestamp,
Expand Down
26 changes: 25 additions & 1 deletion lib/domain/entities/chat/message.dart
Original file line number Diff line number Diff line change
@@ -1,17 +1,41 @@
class Message {
String id;
bool sender;
String messageText;
String timestamp;
int affinityScore;
int rejectionScore;
List<String> reactions;


Message({
required this.id,
required this.sender,
required this.messageText,
required this.timestamp,
required this.affinityScore,
required this.rejectionScore,
});
List<String>? reactions,}) : reactions = reactions ?? [];

// copyWith 메서드 추가
Message copyWith({
String? id,
bool? sender,
String? messageText,
String? timestamp,
int? affinityScore,
int? rejectionScore,
List<String>? reactions,
}) {
return Message(
id: id ?? this.id,
sender: sender ?? this.sender,
messageText: messageText ?? this.messageText,
timestamp: timestamp ?? this.timestamp,
affinityScore: affinityScore ?? this.affinityScore,
rejectionScore: rejectionScore ?? this.rejectionScore,
reactions: reactions ?? this.reactions,
);
}
}

12 changes: 5 additions & 7 deletions lib/domain/usecase/generate_response_usecase.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:get/get.dart';
import 'package:palink_v2/data/mapper/ai_response_mapper.dart';
import 'package:palink_v2/data/models/ai_response/ai_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/di/locator.dart';
import 'package:palink_v2/domain/entities/character/character.dart';
import 'package:palink_v2/domain/entities/chat/message.dart';
Expand All @@ -22,16 +23,14 @@ class GenerateResponseUsecase {

GenerateResponseUsecase(this.getUserInfoUseCase, this.fetchChatHistoryUsecase, this.generateTipUsecase);

Future<AIResponse?> execute(int conversationId, Character character) async {
Future<Map<String?, AIResponse?>> execute(int conversationId, Character character) async {
// STEP1) 사용자 정보 가져오기
User? user = await getUserInfoUseCase.execute();

// STEP2) 이전 대화 기록 페치
final chatHistoryResponse = await fetchChatHistoryUsecase.execute(conversationId);

String chatHistory = _formatChatHistory(chatHistoryResponse!);


// STEP3) AI와의 대화 시작
final inputs = {
'input': '유저의 마지막 말에 대해 대답하세요. 맥락을 기억합니다.',
Expand All @@ -42,12 +41,11 @@ class GenerateResponseUsecase {
};

AIResponse? aiResponse = await aiRepository.processChat(inputs);

MessageResponse? messageResponse;
// STEP 4) AI 응답을 메시지로 변환하여 저장
if (aiResponse != null) {
final messageRequest = aiResponse.toMessageRequest();
await chatRepository.saveMessage(conversationId, messageRequest);

messageResponse = await chatRepository.saveMessage(conversationId, messageRequest);
await aiRepository.saveMemoryContext(inputs, {'response': aiResponse});

final tip = await generateTipUsecase.execute(aiResponse.text);
Expand All @@ -57,7 +55,7 @@ class GenerateResponseUsecase {
: tipViewModel.updateTip('팁 생성 전입니다!');
}

return aiResponse;
return {messageResponse?.messageId.toString(): aiResponse}; // Map 반환
}
// chatHistoryResponse를 JSON 또는 텍스트로 변환하는 함수
String _formatChatHistory(List<Message> chatHistoryResponse) {
Expand Down
2 changes: 1 addition & 1 deletion lib/domain/usecase/send_user_message_usecase.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class SendUserMessageUsecase {
return _mapResponseToDomain(messageResponse);
}

Future<AIResponse?> generateAIResponse(
Future<Map<String?, AIResponse?>> generateAIResponse(
int chatRoomId, Character character) async {
return await generateResponseUsecase.execute(chatRoomId, character);
}
Expand Down
34 changes: 23 additions & 11 deletions lib/presentation/screens/chatting/controller/chat_viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,19 @@ class ChatViewModel extends GetxController {
messages.insert(0, userMessage); // 사용자 메시지를 리스트에 추가
}

var aiResponseMessage = await sendMessageUsecase.generateAIResponse(chatRoomId, character);
if (aiResponseMessage != null) {
var aiMessage = convertAIResponseToMessage(aiResponseMessage);
var responseMap = await sendMessageUsecase.generateAIResponse(chatRoomId, character);
if (responseMap.isNotEmpty) {
Message? aiMessage = convertAIResponseToMessage(responseMap.values.first!, responseMap.keys.first!.toString());
if (aiMessage != null) {
messages.insert(0, aiMessage); // AI 응답 메시지를 리스트에 추가
}

_handleQuestAchievements(responseMap.values.first!); // 퀘스트 달성 확인
_checkIfConversationEnded(responseMap.values.first!); // 대화 종료 여부 확인
textController.clear(); // 메시지 입력창 초기화
} else {
print('AI 응답이 없습니다');
}

_loadMessages(); // 메시지 로드

_handleQuestAchievements(aiResponseMessage!); // 퀘스트 달성 확인
_checkIfConversationEnded(aiResponseMessage!); // 대화 종료 여부 확인
textController.clear(); // 메시지 입력창 초기화
} catch (e) {
print('메시지 전송 실패 : $e');
} finally {
Expand All @@ -94,13 +92,14 @@ class ChatViewModel extends GetxController {


// AIResponse를 Message로 변환하는 메서드
Message? convertAIResponseToMessage(AIResponse aiResponse) {
Message? convertAIResponseToMessage(AIResponse aiResponse, String messageId) {
return Message(
sender: false,
messageText: aiResponse.text,
timestamp: DateTime.now().toIso8601String(),
affinityScore: aiResponse.affinityScore, // 매핑
rejectionScore: aiResponse.rejectionScore // 매핑
rejectionScore: aiResponse.rejectionScore,
id: messageId, // 매핑
);
}

Expand Down Expand Up @@ -144,5 +143,18 @@ class ChatViewModel extends GetxController {
return character.quest;
}

// 유저가 리액션을 하면 메시지에 reaction 추가하기
void addReactionToMessage(Message message, String reaction) {
final updatedReactions = List<String>.from(message.reactions);
updatedReactions.add(reaction);

final index = messages.indexOf(message);
if (index != -1) {
final updatedMessages = List<Message>.from(messages); // 새로운 리스트 복사
updatedMessages[index] = message.copyWith(reactions: updatedReactions); // 업데이트된 메시지 적용
messages.value = updatedMessages; // 새로운 리스트로 할당하여 UI 갱신
}
}


}
Loading
Loading