mirror of
https://github.com/Shchoholiev/shopping-assistant-mobile-client.git
synced 2025-04-12 01:48:50 +00:00
create new logic for chat
This commit is contained in:
parent
08a66e829f
commit
0393a70f88
49
lib/network/search_service.dart
Normal file
49
lib/network/search_service.dart
Normal 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}'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user