diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5701380..240771d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -60,16 +60,21 @@ jobs: uses: ncipollo/release-action@v1 with: artifacts: "build/app/outputs/apk/release/*" - tag: v2.1.1 + tag: v2.1.2 token: ${{ secrets.TOKEN }} - name: "beta-v2.1.1" + name: "stable-v2.1.2" body: | - ## What's New in v2.1.1 + ## What's New in v2.1.2 - - **Settings Tab is now Better and Accessible** + - **Improved AI Chat Functionality** + - **Redis DS Change - HashMaps** + - **Minor Bug fixes** + - **Crash Handlers are improved** + - **Improved Overall Performance - Implemented Impeller** + - **Settings Tab is now Better** - **Redis connection fixes and data privacy improvised** - **Redis Cloud Implementation and Fetching in Beta Phase** - **Added Redis-base to support syncfusion** - **New Feature**: Implemented Syncfusion and Redis for low latency** - ### Known Issues are Resolved - Redis Full-Integration Phase 3 + ### Issues are being Resolved - Redis Full-Integration Phase 3 diff --git a/README.md b/README.md index 1f30dce..0610f86 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Build Status - Version + Version

@@ -17,15 +17,20 @@ **APP STATUS** : ALL CORE FUNCTIONALITIES WORKING (Deployed NodeJs & Postgresql on Render) -## What's New in v2.1.1 (Beta Phase for Redis) (Use Stable Version for Best Experience) +## What's New in v2.1.2 (**Stable Release with Redis Phase 3 Integration**) - - **Settings Tab is now Better and Accessible** + - **Improved AI Chat Functionality** + - **Redis DS Change - HashMaps** + - **Minor Bug fixes** + - **Crash Handlers are improved** + - **Improved Overall Performance - Implemented Impeller** + - **Settings Tab is now Better** - **Redis connection fixes and data privacy improvised** - **Redis Cloud Implementation and Fetching in Beta Phase** - **Added Redis-base to support syncfusion** - **New Feature**: Implemented Syncfusion and Redis for low latency** - - ### Known Issues are Resolved - Redis Full-Integration Phase 3 + + ### Issues are being Resolved - Redis Full-Integration Phase 3 [DEMO LINK OF WORKING](https://vimeo.com/1016496824?share=copy) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 0507bcf..aca3052 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -30,6 +30,9 @@ + diff --git a/assets/background_model.mp4 b/assets/background_model.mp4 new file mode 100644 index 0000000..802c95d Binary files /dev/null and b/assets/background_model.mp4 differ diff --git a/lib/features/meditation/presentation/pages/meditation_page.dart b/lib/features/meditation/presentation/pages/meditation_page.dart index 283ade0..457a54b 100644 --- a/lib/features/meditation/presentation/pages/meditation_page.dart +++ b/lib/features/meditation/presentation/pages/meditation_page.dart @@ -52,7 +52,7 @@ class _MeditationPageState extends State { child: SizedBox( height: 20, child: LottieBuilder.network( - "https://lottie.host/7f8fdd94-95c4-4a11-90bb-edc15af41005/jVxlzL8zAW.json"), + 'https://lottie.host/b4a596fb-3b74-403a-ba62-94e56dd1662c/n0wCMuhZKw.json'), ), ), ), @@ -328,7 +328,7 @@ class _MeditationPageState extends State { dataSources!.clear(); __chartData!.clear(); _annotationSources!.clear(); - }catch(error){} + } catch (error) {} super.dispose(); } @@ -910,7 +910,6 @@ class _MeditationPageState extends State { } if (state is MoodDataError) { - print(state.message); return const Text( "No Data Found", textAlign: TextAlign.center, diff --git a/lib/features/meditation/presentation/pages/settingscreen.dart b/lib/features/meditation/presentation/pages/settingscreen.dart index 369eb18..6b280da 100644 --- a/lib/features/meditation/presentation/pages/settingscreen.dart +++ b/lib/features/meditation/presentation/pages/settingscreen.dart @@ -15,7 +15,6 @@ class SettingScreen extends StatefulWidget { } class _SettingScreenState extends State { - Future? _launched; @override @@ -72,7 +71,7 @@ class _SettingScreenState extends State { body: SingleChildScrollView( scrollDirection: Axis.vertical, child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 25.0, vertical: 60.0), + padding: const EdgeInsets.symmetric(horizontal: 25.0, vertical: 20.0), child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ @@ -166,15 +165,15 @@ class _SettingScreenState extends State { width: 10, ), GestureDetector( - onTap: (){ - - final Uri toLaunch = - Uri(scheme: 'https', host: 'www.postgresql.org',path: '/'); + onTap: () { + final Uri toLaunch = Uri( + scheme: 'https', + host: 'www.postgresql.org', + path: '/'); setState(() { _launched = _launchInAppWithBrowserOptions(toLaunch); }); }, - child: const SizedBox( width: 200, child: Text( @@ -210,10 +209,11 @@ class _SettingScreenState extends State { width: 10, ), GestureDetector( - onTap: (){ - - final Uri toLaunch = - Uri(scheme: 'https', host: 'docs.llama-api.com',path: '/essentials/chat'); + onTap: () { + final Uri toLaunch = Uri( + scheme: 'https', + host: 'docs.llama-api.com', + path: '/essentials/chat'); setState(() { _launched = _launchInAppWithBrowserOptions(toLaunch); }); diff --git a/lib/main.dart b/lib/main.dart index e85d102..01d949d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -109,12 +109,10 @@ class _inPageState extends State { myboxx.put('google', 'true'); first.put("firsttime", 'false'); String? value = GoogleSignInApi.details()?.email; - print(value); + try { context.read().add(FetchMoodData("${value}-google")); - } catch (error) { - print(error); - } + } catch (error) {} Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (BuildContext context) => HomePage()), diff --git a/lib/presentation/chat_screen/chat_with_ai.dart b/lib/presentation/chat_screen/chat_with_ai.dart index 8276afd..b79198a 100644 --- a/lib/presentation/chat_screen/chat_with_ai.dart +++ b/lib/presentation/chat_screen/chat_with_ai.dart @@ -1,7 +1,9 @@ import 'package:flutter/cupertino.dart'; +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:google_generative_ai/google_generative_ai.dart'; import 'package:intl/intl.dart'; +import 'package:video_player/video_player.dart'; class ChatScreen extends StatefulWidget { const ChatScreen({super.key}); @@ -11,96 +13,186 @@ class ChatScreen extends StatefulWidget { } class _ChatScreenState extends State { - TextEditingController _userInput = TextEditingController(); + final TextEditingController _userInput = TextEditingController(); + late VideoPlayerController _controller; - static const apiKey = "AIzaSyBd6AiBrx_5Kt1vQwAtDfHOqt1AztpoZ2s"; + @override + void dispose() { + // TODO: implement dispose + _controller.dispose(); + _userInput.dispose(); + super.dispose(); + } + @override + void initState() { + super.initState(); + _controller = VideoPlayerController.asset('assets/background_model.mp4') + ..initialize().then((_) { + // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed. + setState(() { + _controller.play(); + _controller.setLooping(true); + }); + }); + } + + var scrollController = ScrollController(); + static const apiKey = "AIzaSyBd6AiBrx_5Kt1vQwAtDfHOqt1AztpoZ2s"; final model = GenerativeModel(model: 'gemini-1.5-flash', apiKey: apiKey); final List _messages = []; - + double c = 0; Future sendMessage() async { final message = _userInput.text; setState(() { _messages .add(Message(isUser: true, message: message, date: DateTime.now())); + c++; }); + setState(() { + scrollController.animateTo( + c * 2000, + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + ); + _userInput.text = ''; + }); final content = [Content.text(message)]; final response = await model.generateContent(content); setState(() { _messages.add(Message( isUser: false, message: response.text ?? "", date: DateTime.now())); + c++; + }); + + setState(() { + scrollController.animateTo( + c * 2000, + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + ); + _userInput.text = ''; }); } @override Widget build(BuildContext context) { + final _formKey = GlobalKey(); + bool activation = false; + bool activationfunction() { + activation = true; + return activation; + } + + bool deactivationfunction() { + activation = false; + return activation; + } + return Scaffold( - body: Container( - decoration: BoxDecoration( - image: DecorationImage( - colorFilter: new ColorFilter.mode( - Colors.black.withOpacity(0.8), BlendMode.dstATop), - image: const NetworkImage( - 'https://media.istockphoto.com/id/1850608258/vector/seamless-talking-speech-bubble-conversation-chatting-teamwork-gpt-background.jpg?s=612x612&w=0&k=20&c=nEB5xbclDA-FGFSVN_ttBEHiNS1IJ5NtqRAlZTWlVJI='), - fit: BoxFit.cover)), - child: Column( + backgroundColor: Colors.black, + resizeToAvoidBottomInset: true, + appBar: AppBar( + title: const Text("AI Chat", + style: TextStyle(fontSize: 25, color: Colors.white)), + centerTitle: true, + backgroundColor: Colors.transparent, + ), + body: Stack(children: [ + Center( + child: _controller.value.isInitialized + ? AspectRatio( + aspectRatio: _controller.value.aspectRatio, + child: VideoPlayer(_controller), + ) + : Container(), + ), + Column( mainAxisAlignment: MainAxisAlignment.end, children: [ Expanded( - child: ListView.builder( - itemCount: _messages.length, - itemBuilder: (context, index) { - final message = _messages[index]; - return Messages( - isUser: message.isUser, - message: message.message, - date: DateFormat('HH:mm').format(message.date)); - })), + child: Align( + alignment: Alignment.topCenter, + child: ListView.builder( + shrinkWrap: true, + // reverse: true, + controller: scrollController, + scrollDirection: Axis.vertical, + itemCount: _messages.length, + itemBuilder: (context, index) { + final message = _messages[index]; + return Messages( + isUser: message.isUser, + message: message.message, + date: DateFormat('HH:mm').format(message.date)); + }), + )), Padding( padding: const EdgeInsets.all(8.0), child: Row( + crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( flex: 15, - child: TextFormField( - style: const TextStyle(color: Colors.white), - controller: _userInput, - decoration: InputDecoration( - border: OutlineInputBorder( - borderSide: const BorderSide( - color: Colors.black, width: 10), - borderRadius: BorderRadius.circular(15), - ), - label: const Text( - 'Ask Me Anything', - style: TextStyle(color: Colors.white), - )), + child: Form( + key: _formKey, + child: TextFormField( + style: const TextStyle(color: Colors.white), + controller: _userInput, + autocorrect: false, + textCapitalization: TextCapitalization.values.first, + autovalidateMode: AutovalidateMode.always, + validator: (value) { + if (value!.isEmpty) { + return "Enter Text"; + } + return null; + }, + onChanged: (val) { + if (val.toString() != ' ') { + activationfunction(); + } + }, + decoration: InputDecoration( + border: OutlineInputBorder( + borderSide: const BorderSide( + color: Colors.black, width: 10), + borderRadius: BorderRadius.circular(15), + ), + label: const Text( + 'Ask Me Anything', + style: + TextStyle(fontSize: 16, color: Colors.white), + )), + ), ), ), - const Spacer(), IconButton( - padding: const EdgeInsets.all(12), + padding: const EdgeInsets.only(bottom: 20), iconSize: 30, style: ButtonStyle( - backgroundColor: - WidgetStateProperty.all(Colors.black), foregroundColor: WidgetStateProperty.all(Colors.white), shape: WidgetStateProperty.all(const CircleBorder())), onPressed: () { - sendMessage(); + Future.delayed(const Duration(seconds: 4)); + activation ? sendMessage() : null; + deactivationfunction(); }, - icon: const Icon(Icons.send)) + icon: const Icon( + Icons.send, + size: 30, + )) ], ), ) ], ), - ), + ]), ); } } @@ -130,27 +222,26 @@ class Messages extends StatelessWidget { width: double.infinity, padding: const EdgeInsets.all(15), margin: const EdgeInsets.symmetric(vertical: 15) - .copyWith(left: isUser ? 100 : 10, right: isUser ? 10 : 100), + .copyWith(left: isUser ? 100 : 20, right: isUser ? 20 : 100), decoration: BoxDecoration( - color: isUser ? Colors.black : Colors.white, + color: isUser ? Colors.red : Colors.green, borderRadius: BorderRadius.only( - topLeft: const Radius.circular(10), - bottomLeft: isUser ? const Radius.circular(10) : Radius.zero, - topRight: const Radius.circular(10), - bottomRight: isUser ? Radius.zero : const Radius.circular(10))), + topLeft: const Radius.circular(20), + bottomLeft: isUser ? const Radius.circular(20) : Radius.zero, + topRight: const Radius.circular(20), + bottomRight: isUser ? Radius.zero : const Radius.circular(20))), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( message, - style: TextStyle( - fontSize: 16, color: isUser ? Colors.white : Colors.black), + style: const TextStyle(fontSize: 16, color: Colors.white), ), Text( date, - style: TextStyle( - fontSize: 10, - color: isUser ? Colors.white : Colors.black, + style: const TextStyle( + fontSize: 14, + color: Colors.white, ), ) ], diff --git a/lib/presentation/onboarding/onboarding.dart b/lib/presentation/onboarding/onboarding.dart index d8f8c91..e82c672 100644 --- a/lib/presentation/onboarding/onboarding.dart +++ b/lib/presentation/onboarding/onboarding.dart @@ -1,8 +1,6 @@ import 'package:flutter/material.dart'; import 'package:lottie/lottie.dart'; -import 'package:mental_health/core/theme.dart'; import 'package:mental_health/features/auth/presentation/auth/pages/signup_or_signin.dart'; -import 'package:mental_health/presentation/homePage/home_page.dart'; import 'package:flutter_onboarding_slider/flutter_onboarding_slider.dart'; class Onboarding extends StatelessWidget { @@ -15,6 +13,7 @@ class Onboarding extends StatelessWidget { body: OnBoardingSlider( totalPage: 3, headerBackgroundColor: Colors.white, + pageBackgroundColor: Colors.white, finishButtonText: 'Go to Dashboard', onFinish: () { Navigator.pushAndRemoveUntil( @@ -69,7 +68,7 @@ class Onboarding extends StatelessWidget { (route) => false); }, background: [ - Container( + SizedBox( height: MediaQuery.of(context).size.height * 0.85, width: MediaQuery.of(context).size.width, child: LottieBuilder.network( @@ -117,6 +116,7 @@ class Onboarding extends StatelessWidget { ], speed: 1.5, pageBodies: [ + Stack(children: [ Positioned( left: 0, diff --git a/pubspec.lock b/pubspec.lock index 09d709d..4a52151 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -286,6 +286,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.5" + csslib: + dependency: transitive + description: + name: csslib + sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" + url: "https://pub.dev" + source: hosted + version: "1.0.0" cupertino_icons: dependency: "direct main" description: @@ -645,6 +653,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + html: + dependency: transitive + description: + name: html + sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" + url: "https://pub.dev" + source: hosted + version: "0.15.4" http: dependency: "direct main" description: @@ -1290,6 +1306,46 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + video_player: + dependency: "direct main" + description: + name: video_player + sha256: "4a8c3492d734f7c39c2588a3206707a05ee80cef52e8c7f3b2078d430c84bc17" + url: "https://pub.dev" + source: hosted + version: "2.9.2" + video_player_android: + dependency: transitive + description: + name: video_player_android + sha256: "340b29bc38b2c341ed3afa08148f3d9f351220403cdd2b3a9eb38b71a4be1a9d" + url: "https://pub.dev" + source: hosted + version: "2.7.12" + video_player_avfoundation: + dependency: transitive + description: + name: video_player_avfoundation + sha256: cd5ab8a8bc0eab65ab0cea40304097edc46da574c8c1ecdee96f28cd8ef3792f + url: "https://pub.dev" + source: hosted + version: "2.6.2" + video_player_platform_interface: + dependency: transitive + description: + name: video_player_platform_interface + sha256: "229d7642ccd9f3dc4aba169609dd6b5f3f443bb4cc15b82f7785fcada5af9bbb" + url: "https://pub.dev" + source: hosted + version: "6.2.3" + video_player_web: + dependency: transitive + description: + name: video_player_web + sha256: "6dcdd298136523eaf7dfc31abaf0dfba9aa8a8dbc96670e87e9d42b6f2caf774" + url: "https://pub.dev" + source: hosted + version: "2.3.2" vm_service: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 21180d9..60f195d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: mental_health -description: "A new Flutter project." +description: "Mindful App : Dedicated to Medical Facilities" publish_to: 'none' -version: 2.1.1 +version: 2.1.2 environment: sdk: ^3.5.3 dependencies: @@ -36,6 +36,7 @@ dependencies: hive_flutter: syncfusion_flutter_charts: url_launcher: + video_player: dev_dependencies: flutter_test: sdk: flutter