AI a funcionar
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import 'dart:ui';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class ChatScreen extends StatefulWidget {
|
||||
const ChatScreen({super.key});
|
||||
@@ -21,7 +23,7 @@ class _ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
bool _isTyping = false;
|
||||
|
||||
void _handleSubmitted(String text) {
|
||||
Future<void> _handleSubmitted(String text) async {
|
||||
if (text.trim().isEmpty) return;
|
||||
|
||||
_textController.clear();
|
||||
@@ -31,18 +33,54 @@ class _ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
|
||||
_isTyping = true;
|
||||
});
|
||||
|
||||
// Simulate EPVChat! typing delay
|
||||
Future.delayed(const Duration(milliseconds: 1500), () {
|
||||
try {
|
||||
// Faz o pedido para o IP usando o formato compatível com OpenAI
|
||||
final response = await http
|
||||
.post(
|
||||
Uri.parse('http://192.168.60.134:11434/v1/chat/completions'),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({
|
||||
'model': 'qwen3:4b', // Um modelo disponível no servidor
|
||||
'messages': [
|
||||
{'role': 'user', 'content': text},
|
||||
],
|
||||
'stream': false,
|
||||
}),
|
||||
)
|
||||
.timeout(const Duration(seconds: 30));
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body);
|
||||
final reply =
|
||||
data['choices'][0]['message']['content'] ??
|
||||
'Sem resposta do modelo.';
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isTyping = false;
|
||||
_messages.insert(0, ChatMessage(text: reply, isAssistant: true));
|
||||
});
|
||||
}
|
||||
} else {
|
||||
throw Exception(
|
||||
'Erro no servidor: HTTP ${response.statusCode} - ${response.body}',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isTyping = false;
|
||||
_messages.insert(0, ChatMessage(
|
||||
text: "This is a simulated modern response to: \"$text\"",
|
||||
isAssistant: true,
|
||||
));
|
||||
_messages.insert(
|
||||
0,
|
||||
ChatMessage(
|
||||
text:
|
||||
"Não foi possível comunicar com o modelo.\nVerifique se o IP está acessível.\nDetalhes: $e",
|
||||
isAssistant: true,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildMessage(ChatMessage message) {
|
||||
@@ -50,7 +88,9 @@ class _ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 16.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: isAssistant ? MainAxisAlignment.start : MainAxisAlignment.end,
|
||||
mainAxisAlignment: isAssistant
|
||||
? MainAxisAlignment.start
|
||||
: MainAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
if (isAssistant)
|
||||
@@ -79,19 +119,28 @@ class _ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
|
||||
),
|
||||
Flexible(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 14.0),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 20.0,
|
||||
vertical: 14.0,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
gradient: isAssistant
|
||||
? const LinearGradient(
|
||||
colors: [Color(0xFFF1F5F9), Color(0xFFE2E8F0)], // Light bubbles
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
)
|
||||
: const LinearGradient(
|
||||
colors: [Color(0xFF8ad5c9), Color(0xFF57a7ed)], // Mint & Blue bubbles
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
),
|
||||
? const LinearGradient(
|
||||
colors: [
|
||||
Color(0xFFF1F5F9),
|
||||
Color(0xFFE2E8F0),
|
||||
], // Light bubbles
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
)
|
||||
: const LinearGradient(
|
||||
colors: [
|
||||
Color(0xFF8ad5c9),
|
||||
Color(0xFF57a7ed),
|
||||
], // Mint & Blue bubbles
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
),
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: const Radius.circular(20),
|
||||
topRight: const Radius.circular(20),
|
||||
@@ -106,9 +155,11 @@ class _ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
|
||||
),
|
||||
],
|
||||
border: Border.all(
|
||||
color: isAssistant ? Colors.black.withOpacity(0.05) : Colors.transparent,
|
||||
color: isAssistant
|
||||
? Colors.black.withOpacity(0.05)
|
||||
: Colors.transparent,
|
||||
width: 1,
|
||||
)
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
message.text,
|
||||
@@ -126,7 +177,10 @@ class _ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
gradient: const LinearGradient(
|
||||
colors: [Color(0xFF57a7ed), Color(0xFF3A8BD1)], // User avatar gradient
|
||||
colors: [
|
||||
Color(0xFF57a7ed),
|
||||
Color(0xFF3A8BD1),
|
||||
], // User avatar gradient
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
@@ -172,9 +226,14 @@ class _ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0,
|
||||
vertical: 12.0,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF1F5F9), // Typing bubble matching assistant light bubble
|
||||
color: const Color(
|
||||
0xFFF1F5F9,
|
||||
), // Typing bubble matching assistant light bubble
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(20),
|
||||
topRight: Radius.circular(20),
|
||||
@@ -240,7 +299,9 @@ class _ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF1F5F9), // Light input box background
|
||||
color: const Color(
|
||||
0xFFF1F5F9,
|
||||
), // Light input box background
|
||||
borderRadius: BorderRadius.circular(30.0),
|
||||
border: Border.all(color: Colors.black.withOpacity(0.05)),
|
||||
boxShadow: [
|
||||
@@ -257,9 +318,14 @@ class _ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
|
||||
style: const TextStyle(color: Colors.black87),
|
||||
decoration: InputDecoration(
|
||||
hintText: "Message EPVChat!...",
|
||||
hintStyle: TextStyle(color: Colors.black.withOpacity(0.4)),
|
||||
hintStyle: TextStyle(
|
||||
color: Colors.black.withOpacity(0.4),
|
||||
),
|
||||
border: InputBorder.none,
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 14.0),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 24.0,
|
||||
vertical: 14.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -268,7 +334,10 @@ class _ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: const LinearGradient(
|
||||
colors: [Color(0xFF8ad5c9), Color(0xFF57a7ed)], // Mint & Blue send button
|
||||
colors: [
|
||||
Color(0xFF8ad5c9),
|
||||
Color(0xFF57a7ed),
|
||||
], // Mint & Blue send button
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
@@ -282,7 +351,11 @@ class _ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
|
||||
],
|
||||
),
|
||||
child: IconButton(
|
||||
icon: const Icon(Icons.send_rounded, color: Colors.white, size: 20),
|
||||
icon: const Icon(
|
||||
Icons.send_rounded,
|
||||
color: Colors.white,
|
||||
size: 20,
|
||||
),
|
||||
onPressed: () => _handleSubmitted(_textController.text),
|
||||
),
|
||||
),
|
||||
@@ -306,7 +379,10 @@ class _ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
|
||||
child: AppBar(
|
||||
title: ShaderMask(
|
||||
shaderCallback: (bounds) => const LinearGradient(
|
||||
colors: [Color(0xFF8ad5c9), Color(0xFF57a7ed)], // Text gradient header
|
||||
colors: [
|
||||
Color(0xFF8ad5c9),
|
||||
Color(0xFF57a7ed),
|
||||
], // Text gradient header
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
).createShader(bounds),
|
||||
@@ -319,7 +395,9 @@ class _ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
|
||||
),
|
||||
),
|
||||
),
|
||||
backgroundColor: Colors.white.withOpacity(0.7), // Light Header backgrop
|
||||
backgroundColor: Colors.white.withOpacity(
|
||||
0.7,
|
||||
), // Light Header backgrop
|
||||
elevation: 0,
|
||||
centerTitle: true,
|
||||
bottom: PreferredSize(
|
||||
@@ -342,7 +420,7 @@ class _ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin {
|
||||
Colors.white,
|
||||
Color(0xFFF8FAFC), // Slate 50
|
||||
],
|
||||
)
|
||||
),
|
||||
),
|
||||
child: SafeArea(
|
||||
bottom: false,
|
||||
|
||||
32
pubspec.lock
32
pubspec.lock
@@ -75,6 +75,22 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.2"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -192,6 +208,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.10"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -208,6 +232,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "15.0.2"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
sdks:
|
||||
dart: ">=3.11.1 <4.0.0"
|
||||
flutter: ">=3.18.0-18.0.pre.54"
|
||||
|
||||
@@ -34,6 +34,7 @@ dependencies:
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^1.0.8
|
||||
http: ^1.6.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
Reference in New Issue
Block a user