From 7ca6cc23cafc4e1531a4b4ddc838058419c749b2 Mon Sep 17 00:00:00 2001 From: 240405 <240405@epvc.pt> Date: Sat, 14 Mar 2026 16:42:33 +0000 Subject: [PATCH] =?UTF-8?q?Altera=C3=A7=C3=B5es=20visuais,=20melhorias=20e?= =?UTF-8?q?m=20envio=20de=20mensagem?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/build.gradle.kts | 12 + .../gradle/wrapper/gradle-wrapper.properties | 6 +- android/settings.gradle.kts | 18 +- assets/logo.png | Bin 0 -> 71258 bytes lib/chat_screen.dart | 448 +++++++----------- pubspec.yaml | 72 +-- 6 files changed, 187 insertions(+), 369 deletions(-) create mode 100644 assets/logo.png diff --git a/android/build.gradle.kts b/android/build.gradle.kts index dbee657..0b65f96 100644 --- a/android/build.gradle.kts +++ b/android/build.gradle.kts @@ -1,3 +1,15 @@ +buildscript { + repositories { + google() + mavenCentral() + } + dependencies { + // Versões estáveis e compatíveis com Flutter 3.x + classpath("com.android.tools.build:gradle:7.4.2") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.22") + } +} + allprojects { repositories { google() diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 4dfd444..0d7c5aa 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Mar 13 16:43:00 WET 2026 +#Sat Mar 14 16:08:23 WET 2026 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-bin.zip distributionPath=wrapper/dists -zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts index ca7fe06..a8b39ad 100644 --- a/android/settings.gradle.kts +++ b/android/settings.gradle.kts @@ -1,12 +1,9 @@ pluginManagement { - val flutterSdkPath = - run { - val properties = java.util.Properties() - file("local.properties").inputStream().use { properties.load(it) } - val flutterSdkPath = properties.getProperty("flutter.sdk") - require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } - flutterSdkPath - } + val flutterSdkPath = run { + val properties = java.util.Properties() + file("local.properties").inputStream().use { properties.load(it) } + properties.getProperty("flutter.sdk") ?: throw GradleException("Flutter SDK not found in local.properties") + } includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") @@ -17,10 +14,11 @@ pluginManagement { } } +// No ficheiro android/settings.gradle plugins { id("dev.flutter.flutter-plugin-loader") version "1.0.0" - id("com.android.application") version "8.11.1" apply false - id("org.jetbrains.kotlin.android") version "2.2.20" apply false + id("com.android.application") version "8.3.0" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false } include(":app") diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c6e975d080277cc4d0e9ab26f53b8b26ec63387d GIT binary patch literal 71258 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 vMyAjA+UV7c^VYI00T=!Un0Ifk literal 0 HcmV?d00001 diff --git a/lib/chat_screen.dart b/lib/chat_screen.dart index b61c426..21c4011 100644 --- a/lib/chat_screen.dart +++ b/lib/chat_screen.dart @@ -2,6 +2,7 @@ import 'dart:ui'; import 'package:flutter/material.dart'; import 'dart:convert'; import 'package:http/http.dart' as http; +import 'dart:async'; class ChatScreen extends StatefulWidget { const ChatScreen({super.key}); @@ -22,235 +23,168 @@ class _ChatScreenState extends State with TickerProviderStateMixin { final TextEditingController _textController = TextEditingController(); final ScrollController _scrollController = ScrollController(); bool _isTyping = false; + late AnimationController _typingController; + + @override + void initState() { + super.initState(); + _typingController = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 1200), + )..repeat(); + + Timer(const Duration(seconds: 2), () => _checkAvailableModels()); + } + + Future _checkAvailableModels() async { + try { + final response = await http.get( + Uri.parse('http://89.114.196.110:11434/api/tags'), + ).timeout(const Duration(seconds: 15)); + + if (response.statusCode == 200) { + final data = jsonDecode(response.body); + print("Modelos ok"); + } + } catch (e) { + print("Erro ao listar modelos: $e"); + } + } + + @override + void dispose() { + _typingController.dispose(); + _textController.dispose(); + _scrollController.dispose(); + super.dispose(); + } + + // Função para limpar o chat + void _clearChat() { + setState(() { + _messages.clear(); + _isTyping = false; + }); + } Future _handleSubmitted(String text) async { - if (text.trim().isEmpty) return; + // BLOQUEIO: Se já estiver a escrever (isTyping), ignora o clique + if (text.trim().isEmpty || _isTyping) return; _textController.clear(); setState(() { _messages.insert(0, ChatMessage(text: text)); - _isTyping = true; + _isTyping = true; // Ativa o bloqueio }); try { - // Faz o pedido para o IP usando o formato compatível com OpenAI + final url = Uri.parse('http://89.114.196.110:11434/v1/chat/completions'); + 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)); + url, + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, + body: jsonEncode({ + 'model': 'tinyllama', + 'messages': [{'role': 'user', 'content': text}], + 'stream': false, + }), + ) + .timeout(const Duration(seconds: 60)); if (response.statusCode == 200) { final data = jsonDecode(response.body); - final reply = - data['choices'][0]['message']['content'] ?? - 'Sem resposta do modelo.'; + final reply = data['choices'][0]['message']['content'] ?? 'Sem resposta.'; if (mounted) { setState(() { - _isTyping = false; + _isTyping = false; // Liberta o bloqueio _messages.insert(0, ChatMessage(text: reply, isAssistant: true)); }); } } else { - throw Exception( - 'Erro no servidor: HTTP ${response.statusCode} - ${response.body}', - ); + throw Exception('Erro ${response.statusCode}'); } } catch (e) { if (mounted) { setState(() { - _isTyping = false; + _isTyping = false; // Liberta o bloqueio mesmo em caso de erro _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, - ), + ChatMessage(text: "Erro: $e", isAssistant: true), ); }); } } } + // ... (Mantenha _buildMessage, _buildAvatar, _buildTypingIndicator e _buildAnimatedDot iguais) Widget _buildMessage(ChatMessage message) { bool isAssistant = message.isAssistant; 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) - Container( - margin: const EdgeInsets.only(right: 12), - decoration: BoxDecoration( - shape: BoxShape.circle, - gradient: const LinearGradient( - colors: [Color(0xFF8ad5c9), Color(0xFF57a7ed)], // Mint & Blue - begin: Alignment.topLeft, - end: Alignment.bottomRight, - ), - boxShadow: [ - BoxShadow( - color: const Color(0xFF8ad5c9).withOpacity(0.4), - blurRadius: 8, - offset: const Offset(0, 4), - ), - ], - ), - child: const CircleAvatar( - backgroundColor: Colors.transparent, - radius: 16, - child: Icon(Icons.auto_awesome, color: Colors.white, size: 18), - ), - ), + if (isAssistant) _buildAvatar(Icons.auto_awesome), 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)]) + : const LinearGradient(colors: [Color(0xFF8ad5c9), Color(0xFF57a7ed)]), borderRadius: BorderRadius.only( topLeft: const Radius.circular(20), topRight: const Radius.circular(20), bottomLeft: Radius.circular(isAssistant ? 4 : 20), bottomRight: Radius.circular(isAssistant ? 20 : 4), ), - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.2), - blurRadius: 10, - offset: const Offset(0, 4), - ), - ], - border: Border.all( - color: isAssistant - ? Colors.black.withOpacity(0.05) - : Colors.transparent, - width: 1, - ), ), child: Text( message.text, - style: TextStyle( - color: isAssistant ? Colors.black87 : Colors.white, - fontSize: 15, - height: 1.4, - ), + style: TextStyle(color: isAssistant ? Colors.black87 : Colors.white), ), ), ), - if (!isAssistant) - Container( - margin: const EdgeInsets.only(left: 12), - decoration: BoxDecoration( - shape: BoxShape.circle, - gradient: const LinearGradient( - colors: [ - Color(0xFF57a7ed), - Color(0xFF3A8BD1), - ], // User avatar gradient - begin: Alignment.topLeft, - end: Alignment.bottomRight, - ), - boxShadow: [ - BoxShadow( - color: const Color(0xFF57a7ed).withOpacity(0.3), - blurRadius: 8, - offset: const Offset(0, 4), - ), - ], - ), - child: const CircleAvatar( - backgroundColor: Colors.transparent, - radius: 16, - child: Icon(Icons.person, color: Colors.white, size: 18), - ), - ), + if (!isAssistant) _buildAvatar(Icons.person), ], ), ); } + Widget _buildAvatar(IconData icon) { + return Container( + margin: EdgeInsets.only(left: icon == Icons.person ? 12 : 0, right: icon == Icons.auto_awesome ? 12 : 0), + decoration: const BoxDecoration( + shape: BoxShape.circle, + gradient: LinearGradient(colors: [Color(0xFF8ad5c9), Color(0xFF57a7ed)]), + ), + child: CircleAvatar(backgroundColor: Colors.transparent, radius: 16, child: Icon(icon, color: Colors.white, size: 18)), + ); + } + Widget _buildTypingIndicator() { return Padding( padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 16.0), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ + _buildAvatar(Icons.auto_awesome), Container( - margin: const EdgeInsets.only(right: 12), - decoration: const BoxDecoration( - shape: BoxShape.circle, - gradient: LinearGradient( - colors: [Color(0xFF8ad5c9), Color(0xFF57a7ed)], // Mint & Blue - begin: Alignment.topLeft, - end: Alignment.bottomRight, - ), - ), - child: const CircleAvatar( - backgroundColor: Colors.transparent, - radius: 16, - child: Icon(Icons.auto_awesome, color: Colors.white, size: 18), - ), - ), - 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 - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(20), - topRight: Radius.circular(20), - bottomLeft: Radius.circular(4), - bottomRight: Radius.circular(20), - ), - border: Border.all(color: Colors.black.withOpacity(0.05)), + color: const Color(0xFFF1F5F9), + borderRadius: const BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20), bottomLeft: Radius.circular(4), bottomRight: Radius.circular(20)), ), child: Row( mainAxisSize: MainAxisSize.min, - children: [ - _buildDot(0), - const SizedBox(width: 4), - _buildDot(1), - const SizedBox(width: 4), - _buildDot(2), - ], + children: [_buildAnimatedDot(0), const SizedBox(width: 4), _buildAnimatedDot(1), const SizedBox(width: 4), _buildAnimatedDot(2)], ), ), ], @@ -258,21 +192,15 @@ class _ChatScreenState extends State with TickerProviderStateMixin { ); } - Widget _buildDot(int index) { - return TweenAnimationBuilder( - tween: Tween(begin: 0, end: 1), - duration: const Duration(milliseconds: 600), - builder: (context, double value, child) { + Widget _buildAnimatedDot(int index) { + return AnimatedBuilder( + animation: _typingController, + builder: (context, child) { + double value = (_typingController.value + (index * 0.15)) % 1.0; + double intensity = 1.0 - (value - 0.5).abs() * 2; return Opacity( - opacity: (value + (index * 0.3)) % 1.0, - child: Container( - width: 6, - height: 6, - decoration: const BoxDecoration( - color: Colors.black54, - shape: BoxShape.circle, - ), - ), + opacity: 0.3 + (0.7 * intensity), + child: Transform.translate(offset: Offset(0, -3 * intensity), child: Container(width: 6, height: 6, decoration: const BoxDecoration(color: Colors.black54, shape: BoxShape.circle))), ); }, ); @@ -285,78 +213,51 @@ class _ChatScreenState extends State with TickerProviderStateMixin { child: Container( padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0), decoration: BoxDecoration( - color: Colors.white.withOpacity(0.8), // Light backdrop - border: Border( - top: BorderSide( - color: Colors.black.withOpacity(0.05), - width: 0.5, - ), - ), + color: Colors.white.withOpacity(0.8), + border: Border(top: BorderSide(color: Colors.black.withOpacity(0.05), width: 0.5)), ), child: SafeArea( child: Row( children: [ + // BOTÃO APAGAR CHAT + IconButton( + icon: const Icon(Icons.delete_sweep_rounded, color: Colors.redAccent), + onPressed: _isTyping ? null : _clearChat, // Desativa enquanto digita + ), Expanded( child: Container( decoration: BoxDecoration( - color: const Color( - 0xFFF1F5F9, - ), // Light input box background + color: const Color(0xFFF1F5F9), borderRadius: BorderRadius.circular(30.0), border: Border.all(color: Colors.black.withOpacity(0.05)), - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.2), - blurRadius: 8, - offset: const Offset(0, 2), - ), - ], ), child: TextField( controller: _textController, + enabled: !_isTyping, // Bloqueia o campo de texto onSubmitted: _handleSubmitted, - style: const TextStyle(color: Colors.black87), decoration: InputDecoration( - hintText: "Message EPVChat!...", - hintStyle: TextStyle( - color: Colors.black.withOpacity(0.4), - ), + hintText: _isTyping ? "Aguarde a resposta..." : "Mensagem EPVChat...", border: InputBorder.none, - contentPadding: const EdgeInsets.symmetric( - horizontal: 24.0, - vertical: 14.0, - ), + contentPadding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 14.0), ), ), ), ), - const SizedBox(width: 12), + const SizedBox(width: 8), Container( decoration: BoxDecoration( - gradient: const LinearGradient( - colors: [ - Color(0xFF8ad5c9), - Color(0xFF57a7ed), - ], // Mint & Blue send button + gradient: LinearGradient( + colors: _isTyping + ? [Colors.grey, Colors.grey] // Cor de desativado + : [const Color(0xFF8ad5c9), const Color(0xFF57a7ed)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), shape: BoxShape.circle, - boxShadow: [ - BoxShadow( - color: const Color(0xFF8ad5c9).withOpacity(0.4), - blurRadius: 8, - offset: const Offset(0, 4), - ), - ], ), child: IconButton( - icon: const Icon( - Icons.send_rounded, - color: Colors.white, - size: 20, - ), - onPressed: () => _handleSubmitted(_textController.text), + icon: const Icon(Icons.send_rounded, color: Colors.white), + onPressed: _isTyping ? null : () => _handleSubmitted(_textController.text), ), ), ], @@ -369,83 +270,56 @@ class _ChatScreenState extends State with TickerProviderStateMixin { @override Widget build(BuildContext context) { + final screenWidth = MediaQuery.of(context).size.width; + return Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: const Size.fromHeight(kToolbarHeight), - child: ClipRRect( - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: AppBar( - title: ShaderMask( - shaderCallback: (bounds) => const LinearGradient( - colors: [ - Color(0xFF8ad5c9), - Color(0xFF57a7ed), - ], // Text gradient header - begin: Alignment.topLeft, - end: Alignment.bottomRight, - ).createShader(bounds), - child: const Text( - 'EPVChat!', - style: TextStyle( - fontWeight: FontWeight.w800, - fontSize: 22, - letterSpacing: -0.5, + backgroundColor: Colors.white, + body: Column( + children: [ + Expanded( + child: ListView( + controller: _scrollController, + reverse: true, // Mantém a lógica de mensagens novas em baixo + children: [ + // As mensagens vêm primeiro (no reverse: true, o topo da lista é o fundo do ecrã) + ...(_isTyping ? [_buildTypingIndicator()] : []), + ..._messages.map((msg) => _buildMessage(msg)), + + // O LOGO E O SOMBREADO AGORA SÃO O ÚLTIMO ITEM DO LISTVIEW + // Quando o utilizador sobe o chat, eles sobem junto + Padding( + padding: const EdgeInsets.only(bottom: 50, top: 20), + child: Stack( + alignment: Alignment.center, + children: [ + // O Sombreado Verde + Container( + height: screenWidth * 0.8, + decoration: BoxDecoration( + shape: BoxShape.circle, + gradient: RadialGradient( + colors: [ + const Color(0xFF8ad5c9).withOpacity(0.4), + const Color(0xFF8ad5c9).withOpacity(0.0), + ], + ), + ), + ), + // O Logo + Image.asset( + 'assets/logo.png', + height: 170, + fit: BoxFit.contain, + ), + ], ), ), - ), - backgroundColor: Colors.white.withOpacity( - 0.7, - ), // Light Header backgrop - elevation: 0, - centerTitle: true, - bottom: PreferredSize( - preferredSize: const Size.fromHeight(1.0), - child: Container( - color: Colors.black.withOpacity(0.05), - height: 1.0, - ), - ), + ], ), ), - ), - ), - body: Container( - decoration: const BoxDecoration( - gradient: RadialGradient( - center: Alignment.topCenter, - radius: 1.5, - colors: [ - Colors.white, - Color(0xFFF8FAFC), // Slate 50 - ], - ), - ), - child: SafeArea( - bottom: false, - child: Column( - children: [ - Expanded( - child: ListView.builder( - controller: _scrollController, - padding: const EdgeInsets.symmetric(vertical: 20.0), - reverse: true, - itemCount: _messages.length + (_isTyping ? 1 : 0), - itemBuilder: (_, int index) { - if (_isTyping && index == 0) { - return _buildTypingIndicator(); - } - int messageIndex = _isTyping ? index - 1 : index; - return _buildMessage(_messages[messageIndex]); - }, - ), - ), - _buildTextComposer(), - ], - ), - ), + _buildTextComposer(), + ], ), ); } -} +} \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 4b40485..791ffae 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,90 +1,24 @@ name: app description: "A new Flutter project." -# The following line prevents the package from being accidentally published to -# pub.dev using `flutter pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev +publish_to: 'none' -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -# In Windows, build-name is used as the major, minor, and patch parts -# of the product and file versions while build-number is used as the build suffix. version: 1.0.0+1 environment: sdk: ^3.11.1 -# Dependencies specify other packages that your package needs in order to work. -# To automatically upgrade your package dependencies to the latest versions -# consider running `flutter pub upgrade --major-versions`. Alternatively, -# dependencies can be manually updated by changing the version numbers below to -# the latest version available on pub.dev. To see which dependencies have newer -# versions available, run `flutter pub outdated`. dependencies: flutter: sdk: flutter - - # 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: sdk: flutter - - # The "flutter_lints" package below contains a set of recommended lints to - # encourage good coding practices. The lint set provided by the package is - # activated in the `analysis_options.yaml` file located at the root of your - # package. See that file for information about deactivating specific lint - # rules and activating additional ones. flutter_lints: ^6.0.0 -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter packages. flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/to/resolution-aware-images - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/to/asset-from-package - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/to/font-from-package + assets: + - assets/logo.png