create new logic for chat

This commit is contained in:
stasex 2023-11-23 13:51:10 +02:00
parent 08a66e829f
commit 0393a70f88
2 changed files with 111 additions and 106 deletions

View File

@ -0,0 +1,49 @@
// search_service.dart
import 'package:graphql_flutter/graphql_flutter.dart';
import '../network/api_client.dart';
import '../network/authentication_service.dart';
import '../screens/chat.dart';
const String startPersonalWishlistMutations = r'''
mutation startPersonalWishlist($dto: WishlistCreateDtoInput!) {
startPersonalWishlist(dto: $dto) {
createdById, id, name, type
}
}
''';
class SearchService {
final AuthenticationService _authenticationService = AuthenticationService();
final ApiClient client = ApiClient();
Future<void> initializeAuthenticationService() async {
await _authenticationService.initialize();
}
Future<void> startPersonalWishlist(String message, Function(Message) handleSSEMessage) async {
await _authenticationService.initialize();
final options = MutationOptions(
document: gql(startPersonalWishlistMutations),
variables: <String, dynamic>{
'dto': {'firstMessageText': message, 'type': 'Product'},
},
);
final result = await client.mutate(options);
if (result != null && result.containsKey('startPersonalWishlist')) {
final wishlistId = result['startPersonalWishlist']['id'];
final sseStream = client.getServerSentEventStream(
'api/productssearch/search/$wishlistId',
{'text': message},
);
await for (final chunk in sseStream) {
print('${chunk.event}: ${chunk.data}');
handleSSEMessage(Message(text: '${chunk.event}: ${chunk.data}'));
}
}
}
}

View File

@ -1,135 +1,92 @@
import 'dart:convert'; // search_screen.dart
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:shopping_assistant_mobile_client/network/search_service.dart';
import 'package:shopping_assistant_mobile_client/network/api_client.dart';
const String startPersonalWishlistMutations = r''' class Message {
mutation startPersonalWishlist($dto: WishlistCreateDtoInput!) { final String text;
startPersonalWishlist(dto: $dto) { final bool isUser;
createdById, id, name, type
}
}
''';
const String sendMessageMutation = r''' Message({required this.text, this.isUser = false});
mutation sendMessage($wishlistId: ID!, $message: String!) {
sendMessage(wishlistId: $wishlistId, message: $message) {
// Опис того, що ви очікуєте від відповіді
}
}
''';
final ApiClient client = ApiClient();
class ChatScreen extends StatefulWidget {
@override
State createState() => ChatScreenState();
} }
class MessageBubble extends StatelessWidget { class MessageBubble extends StatelessWidget {
final String message; final String message;
final bool isOutgoing;
MessageBubble({required this.message}); MessageBubble({required this.message, this.isOutgoing = true});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Align( return Align(
alignment: Alignment.centerRight, alignment: isOutgoing ? Alignment.centerRight : Alignment.centerLeft,
child: Container( child: Container(
margin: const EdgeInsets.all(8.0), margin: const EdgeInsets.all(8.0),
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.blue, color: isOutgoing ? Colors.blue : Colors.white,
borderRadius: BorderRadius.circular(10.0), borderRadius: BorderRadius.circular(10.0),
), ),
child: Text( child: Text(
message, message,
style: TextStyle(color: Colors.white), style: TextStyle(color: isOutgoing ? Colors.white : Colors.black),
), ),
), ),
); );
} }
} }
class ChatScreenState extends State<ChatScreen> { class ChatScreen extends StatefulWidget {
@override
State createState() => ChatScreenState();
}
class ChatScreenState extends State<ChatScreen> {
final SearchService _searchService = SearchService();
List<Message> messages = [];
final TextEditingController _messageController = TextEditingController(); final TextEditingController _messageController = TextEditingController();
List<String> messages = [];
bool buttonsVisible = true; bool buttonsVisible = true;
final ScrollController _scrollController = ScrollController(); final ScrollController _scrollController = ScrollController();
String wishlistId = ''; String wishlistId = '';
// Функція для старту першої вішлісту при відправці першого повідомлення void _handleSSEMessage(Message message) {
Future<void> _startPersonalWishlist() async {
final options = MutationOptions(
document: gql(startPersonalWishlistMutations),
variables: <String, dynamic>{
'dto': {'firstMessageText': messages.first, 'type': 'Product'},
},
);
final result = await client.mutate(options);
if (result != null && result.containsKey('startPersonalWishlist')) {
setState(() {
wishlistId = result['startPersonalWishlist']['id'];
});
}
}
// Функція для відправки повідомлення до API
Future<void> _sendMessageToAPI(String message) async {
final options = MutationOptions(
document: gql(sendMessageMutation),
variables: <String, dynamic>{'wishlistId': wishlistId, 'message': message},
);
final result = await client.mutate(options);
// Обробка результатів відправки повідомлення
if (result != null && result.containsKey('sendMessage')) {
// Отримання та обробка відповідей з GPT-4
var sseStream = client.getServerSentEventStream(
'api/productssearch/search/$wishlistId',
{'text': message},
);
await for (var chunk in sseStream) {
print('${chunk.event}: ${chunk.data}');
// Оновлення UI або збереження результатів, якщо необхідно
}
}
}
// Функція для відправки повідомлення
void _sendMessage() {
String message = _messageController.text;
setState(() { setState(() {
messages.insert(0, message); messages.add(message);
});
}
Future<void> _startPersonalWishlist(String message) async {
await _searchService.initializeAuthenticationService();
await _searchService.startPersonalWishlist(message, _handleSSEMessage);
}
Future<void> _sendMessageToAPI(String message) async {
await _searchService.startPersonalWishlist(message, _handleSSEMessage);
setState(() {
messages.add(Message(text: message, isUser: true));
});
}
void _sendMessage() {
final message = _messageController.text;
setState(() {
messages.add(Message(text: message, isUser: true));
}); });
if (wishlistId.isEmpty) { if (wishlistId.isEmpty) {
// Якщо вішліст не створено, стартуємо його _startPersonalWishlist(message);
_startPersonalWishlist().then((_) {
// Після створення вішлісту, відправляємо перше повідомлення до API
_sendMessageToAPI(message);
});
} else { } else {
// Якщо вішліст вже існує, відправляємо повідомлення до API
_sendMessageToAPI(message); _sendMessageToAPI(message);
} }
_messageController.clear(); _messageController.clear();
_scrollController.animateTo( _scrollController.animateTo(
0.0, _scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 300), duration: Duration(milliseconds: 300),
curve: Curves.easeOut, curve: Curves.easeOut,
); );}
}
void _showGiftNotAvailable() { void _showGiftNotAvailable() {
showDialog( showDialog(
@ -156,11 +113,10 @@ class ChatScreenState extends State<ChatScreen> {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text('New Chat'), title: Text('New Chat'),
centerTitle: true, // Відцентрувати заголовок centerTitle: true,
leading: IconButton( leading: IconButton(
icon: Icon(Icons.arrow_back), icon: Icon(Icons.arrow_back),
onPressed: () { onPressed: () {
// Обробник для кнопки "Назад"
print('Back button pressed'); print('Back button pressed');
}, },
), ),
@ -182,29 +138,28 @@ class ChatScreenState extends State<ChatScreen> {
children: <Widget>[ children: <Widget>[
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
// Обробник для кнопки "Product"
print('Product button pressed'); print('Product button pressed');
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 16), padding: EdgeInsets.symmetric(horizontal: 30, vertical: 16),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10), // Закруглення країв borderRadius: BorderRadius.circular(10),
), ),
primary: Colors.blue, // Колір кнопки primary: Colors.blue,
onPrimary: Colors.white, // Колір тексту на активній кнопці onPrimary: Colors.white,
), ),
child: Text('Product'), child: Text('Product'),
), ),
SizedBox(width: 16.0), // Простір між кнопками SizedBox(width: 16.0),
ElevatedButton( ElevatedButton(
onPressed: _showGiftNotAvailable, onPressed: _showGiftNotAvailable,
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 16), padding: EdgeInsets.symmetric(horizontal: 30, vertical: 16),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10), // Закруглення країв borderRadius: BorderRadius.circular(10),
), ),
primary: Colors.white, // Колір кнопки "Gift" primary: Colors.white,
onPrimary: Colors.black, // Колір тексту на активній кнопці onPrimary: Colors.black,
), ),
child: Text('Gift'), child: Text('Gift'),
), ),
@ -215,16 +170,17 @@ class ChatScreenState extends State<ChatScreen> {
), ),
), ),
Expanded( Expanded(
child: ListView( child: ListView.builder(
controller: _scrollController, controller: _scrollController,
reverse: true, // Щоб список був у зворотньому порядку reverse: false,
children: <Widget>[ itemCount: messages.length,
// Повідомлення користувача itemBuilder: (context, index) {
for (var message in messages) final message = messages[index];
MessageBubble( return MessageBubble(
message: message, message: message.text,
), isOutgoing: message.isUser,
], );
},
), ),
), ),
Container( Container(
@ -250,4 +206,4 @@ class ChatScreenState extends State<ChatScreen> {
), ),
); );
} }
} }