diff --git a/lib/core/data.dart b/lib/core/data.dart index d254f5e..0f76d7a 100644 --- a/lib/core/data.dart +++ b/lib/core/data.dart @@ -7,7 +7,7 @@ import 'package:uuid/uuid.dart'; class Data { Loader load = Loader(); - static var uuid = Uuid(); + static var uuid = const Uuid(); static String? userId = FirebaseAuth.instance.currentUser?.uid; static List apps = []; static List selected_apps = []; @@ -42,9 +42,9 @@ class Video { } Map toJson() { return { - 'title': this.title, - 'videoId': this.videoId, - 'videoDescription': this.videoDescription, + 'title': title, + 'videoId': videoId, + 'videoDescription': videoDescription, }; } } diff --git a/lib/core/loader.dart b/lib/core/loader.dart index ebb2fff..f4a6b71 100644 --- a/lib/core/loader.dart +++ b/lib/core/loader.dart @@ -164,15 +164,15 @@ class Loader { Future> loadMessages() async { SharedPreferences prefs = await SharedPreferences.getInstance(); List messages = prefs.getStringList('messages') ?? []; - List message_list = []; + List messageList = []; for (var message in messages) { try { - message_list.add(types.TextMessage.fromJson(jsonDecode(message))); + messageList.add(types.TextMessage.fromJson(jsonDecode(message))); } catch (e) { print('Error decoding message: $e, $message'); } } - return message_list; + return messageList; } Future loadcompletion() async { diff --git a/lib/core/notifications.dart b/lib/core/notifications.dart index 9cbe895..c409d02 100644 --- a/lib/core/notifications.dart +++ b/lib/core/notifications.dart @@ -27,12 +27,12 @@ class LocalNotificationService { priority: Priority.high, ticker: 'ticker'); - int notification_id = 1; + int notificationId = 1; const NotificationDetails notificationDetails = NotificationDetails(android: androidNotificationDetails); await flutterLocalNotificationsPlugin.show( - notification_id, title, value, notificationDetails, + notificationId, title, value, notificationDetails, payload: 'item x'); } } diff --git a/lib/home/chat_page.dart b/lib/home/chat_page.dart index ec9e365..f96e306 100644 --- a/lib/home/chat_page.dart +++ b/lib/home/chat_page.dart @@ -23,10 +23,12 @@ class ChatPage extends StatefulWidget { } class _ChatPageState extends State { - final _user = const types.User(id: '82091008-a484-4a89-ae75-a22bf8d6f3ac'); - final _mentor = const types.User(id: 'mentor'); + final _user = const types.User(id: 'user'); + final _mentor = const types.User( + id: '82091008-a484-4a89-ae75-a22bf8d6f3ac', firstName: "Mentor"); DataProcessor sender = DataProcessor(); - Loader _loader = Loader(); + List typing_users = []; + final Loader _loader = Loader(); @override void initState() { super.initState(); @@ -44,23 +46,18 @@ class _ChatPageState extends State { @override Widget build(BuildContext context) => Scaffold( appBar: AppBar( - title: Text("Mentor/Chat"), + title: const Text("Mentor/Chat"), centerTitle: true, ), body: Chat( messages: Data.messages_data, onSendPressed: _handleSendPressed, user: _user, - typingIndicatorOptions: TypingIndicatorOptions(), + typingIndicatorOptions: + TypingIndicatorOptions(typingUsers: typing_users), ), ); - void _addMessage(types.Message message) { - setState(() { - Data.messages_data.insert(0, message); - }); - } - void _handleSendPressed(types.PartialText message) async { final textMessage = types.TextMessage( author: _user, @@ -68,7 +65,10 @@ class _ChatPageState extends State { id: Data.uuid.v1(), text: message.text, ); - _addMessage(textMessage); + setState(() { + Data.messages_data.insert(0, textMessage); + typing_users = [_mentor]; + }); http.Response response = await sender.meet_with_server(message.text); if (response.statusCode == 200) { @@ -76,6 +76,7 @@ class _ChatPageState extends State { if (mounted) { setState(() { Data.messages_data; + typing_users = []; }); } } else { diff --git a/lib/home/home_page.dart b/lib/home/home_page.dart index e27f3c4..ad1d370 100644 --- a/lib/home/home_page.dart +++ b/lib/home/home_page.dart @@ -86,6 +86,10 @@ class _MentorPageState extends State { setState(() { Data.completion_message = completionMessage ?? ""; result = Data.completion_message; + if (result == '') { + isLoading = true; + _Makerequest(interest); + } }); }); @@ -100,12 +104,6 @@ class _MentorPageState extends State { change_val(); }); } - if (result == '') { - setState(() { - isLoading = true; - _Makerequest(interest); - }); - } } void change_val() { @@ -150,10 +148,10 @@ class _MentorPageState extends State { builder: (context) => const AppsPage()), ); }, - title: Row( + title: const Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - const Text( + Text( "Apps", style: TextStyle(fontSize: 25), ), @@ -168,13 +166,13 @@ class _MentorPageState extends State { builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { - return Center( + return const Center( child: CircularProgressIndicator(), ); // Loading animation } else if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); } else if (snapshot.data!.isEmpty) { - return Text( + return const Text( 'Select the apps you want to display by long pressing. If changes didn\'t show up click the home again'); } else { return ListView.builder( @@ -247,7 +245,7 @@ class _MentorPageState extends State { children: [ Text( lastJournalTitle, - style: TextStyle(fontSize: 25), + style: const TextStyle(fontSize: 25), ), IconButton( tooltip: "Add", @@ -312,7 +310,7 @@ class _MentorPageState extends State { onTap: () { Navigator.push( context, - MaterialPageRoute(builder: (context) => ChatPage()), + MaterialPageRoute(builder: (context) => const ChatPage()), ); }, child: Card( diff --git a/lib/home/make_request.dart b/lib/home/make_request.dart index 714c2b9..3c2f028 100644 --- a/lib/home/make_request.dart +++ b/lib/home/make_request.dart @@ -116,7 +116,7 @@ class DataProcessor { Data.completion_message = ''; for (var message in completionMemory['reply']) { final mentorMessage = types.TextMessage( - author: types.User(id: 'mentor'), + author: const types.User(id: 'mentor'), createdAt: DateTime.now().millisecondsSinceEpoch, id: Data.uuid.v1(), text: message, diff --git a/lib/home/video_page.dart b/lib/home/video_page.dart index fe7ba5e..d182636 100644 --- a/lib/home/video_page.dart +++ b/lib/home/video_page.dart @@ -1,59 +1,87 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:youtube_player_flutter/youtube_player_flutter.dart'; import 'package:url_launcher/url_launcher.dart'; -class VideoPage extends StatelessWidget { +class VideoPage extends StatefulWidget { final String videoId; final String description; - const VideoPage( - {super.key, required this.videoId, required this.description}); + const VideoPage({Key? key, required this.videoId, required this.description}) + : super(key: key); @override - Widget build(BuildContext context) { - final youtubePlayerController = YoutubePlayerController( - initialVideoId: videoId, + _VideoPageState createState() => _VideoPageState(); +} + +class _VideoPageState extends State { + late final YoutubePlayerController youtubePlayerController; + + @override + void initState() { + super.initState(); + SystemChrome.setPreferredOrientations([ + DeviceOrientation.portraitUp, + DeviceOrientation.portraitDown, + ]); + + youtubePlayerController = YoutubePlayerController( + initialVideoId: widget.videoId, flags: const YoutubePlayerFlags( autoPlay: false, ), ); + } + @override + void dispose() { + SystemChrome.setPreferredOrientations([ + DeviceOrientation.portraitUp, + DeviceOrientation.portraitDown, + ]); + super.dispose(); + } + + @override + Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Mentor/Video')), - body: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - mainAxisAlignment: MainAxisAlignment.center, + body: YoutubePlayerBuilder( + player: YoutubePlayer( + controller: youtubePlayerController, + showVideoProgressIndicator: true, + progressIndicatorColor: const Color.fromARGB(255, 50, 204, 102), + ), + builder: (context, player) { + return Column( children: [ IconButton( icon: const Icon(Icons.open_in_browser, color: Color.fromARGB(255, 50, 204, 102)), onPressed: () { - _launchURL(videoId); + _launchURL(widget.videoId); }, ), const SizedBox( height: 2, ), - YoutubePlayer( - controller: youtubePlayerController, - showVideoProgressIndicator: true, - progressIndicatorColor: - const Color.fromARGB(255, 50, 204, 102), - ), + // some widgets + player, const SizedBox(height: 16.0), - Text(description), - ])), + Text(widget.description), + //some other widgets + ], + ); + }), ); } -} -_launchURL(String videoId) async { - final url = 'https://www.youtube.com/watch?v=$videoId'; - Uri uri = Uri.parse(url); - if (!await canLaunchUrl(uri)) { - throw Exception('Could not launch $url'); + _launchURL(String videoId) async { + final url = 'https://www.youtube.com/watch?v=$videoId'; + Uri uri = Uri.parse(url); + if (!await canLaunchUrl(uri)) { + throw Exception('Could not launch $url'); + } + await launchUrl(uri); } - await launchUrl(uri); } diff --git a/lib/journal/journal_page.dart b/lib/journal/journal_page.dart index 6feb0a3..1efda93 100644 --- a/lib/journal/journal_page.dart +++ b/lib/journal/journal_page.dart @@ -73,7 +73,7 @@ class _JournalPageState extends State { child: ListTile( title: Text( title.toString(), - style: TextStyle(fontSize: 25), + style: const TextStyle(fontSize: 25), ), subtitle: Text(content), onTap: () { diff --git a/lib/main.dart b/lib/main.dart index 40c37e6..71a71c7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,3 @@ -import 'package:Mentor/setup/setup_roller.dart'; - import 'settings/knowingthestudent.dart'; import 'package:flutter/material.dart'; import 'home/home_page.dart'; @@ -76,12 +74,12 @@ class MyApp extends StatelessWidget { builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.connectionState == ConnectionState.active) { if (snapshot.data == null) { - return EmailAuth(); + return const EmailAuth(); } else { - return MentorPage(); + return const MentorPage(); } } - return CircularProgressIndicator(); + return const CircularProgressIndicator(); }), routes: { //main pages @@ -95,7 +93,7 @@ class MyApp extends StatelessWidget { '/habiticaIntegrationPage': (context) => const HabiticaIntegrationPage(), '/knowingthestudent': (context) => const Knowingthestudent(), - '/preferredtime': (context) => PreferredTimePage(), + '/preferredtime': (context) => const PreferredTimePage(), }, ); } diff --git a/lib/settings/knowingthestudent.dart b/lib/settings/knowingthestudent.dart index b604796..4852ec8 100644 --- a/lib/settings/knowingthestudent.dart +++ b/lib/settings/knowingthestudent.dart @@ -90,14 +90,14 @@ class _KnowingthestudentState extends State { ), const SizedBox(height: 16), const Text( - "Tell me about your personality", + "Tell me about yourself.", ), const SizedBox(height: 10), TextFormField( controller: _selfPerceptionController, validator: (value) { if (value == null || value.isEmpty) { - return 'This is used to know your current mental state'; + return 'This is used to know your current workable factor'; } return null; // Return null if the value is valid }, diff --git a/lib/settings/parent_mode.dart b/lib/settings/parent_mode.dart index 1b81614..28bee28 100644 --- a/lib/settings/parent_mode.dart +++ b/lib/settings/parent_mode.dart @@ -3,6 +3,8 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import '../core/data.dart'; class EmailSettingsPage extends StatefulWidget { + const EmailSettingsPage({super.key}); + @override _EmailSettingsPageState createState() => _EmailSettingsPageState(); } @@ -31,7 +33,7 @@ class _EmailSettingsPageState extends State { .then((_) => print('Updated successfully')) .catchError((error) => print('Update failed: $error')); ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text('Email saved successfully')), + const SnackBar(content: Text('Email saved successfully')), ); Navigator.pop(context); } @@ -53,26 +55,26 @@ class _EmailSettingsPageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('Mentor/Parental Controls'), + title: const Text('Mentor/Parental Controls'), ), body: Padding( - padding: EdgeInsets.all(16.0), + padding: const EdgeInsets.all(16.0), child: Form( key: _formKey, child: Column( children: [ - Text( + const Text( 'Enter your email address to receive notifications about your child\'s behavior.', style: TextStyle(fontSize: 16), // Adjust the text style as needed ), - SizedBox( + const SizedBox( height: 10, ), TextFormField( controller: _emailController, keyboardType: TextInputType.emailAddress, - decoration: InputDecoration( + decoration: const InputDecoration( labelText: 'Email', ), validator: (value) { @@ -86,10 +88,10 @@ class _EmailSettingsPageState extends State { return null; }, ), - SizedBox(height: 16.0), + const SizedBox(height: 16.0), ElevatedButton( onPressed: _saveEmail, - child: Text('Save'), + child: const Text('Save'), ), ], ), diff --git a/lib/settings/preferred_time.dart b/lib/settings/preferred_time.dart index e0ca20f..0bd3a20 100644 --- a/lib/settings/preferred_time.dart +++ b/lib/settings/preferred_time.dart @@ -2,9 +2,10 @@ import 'package:Mentor/core/loader.dart'; import 'package:flutter/material.dart'; import 'package:android_alarm_manager_plus/android_alarm_manager_plus.dart'; -import 'dart:ui'; class PreferredTimePage extends StatefulWidget { + const PreferredTimePage({super.key}); + @override _PreferredTimePageState createState() => _PreferredTimePageState(); } @@ -14,20 +15,22 @@ class _PreferredTimePageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('Select Preferred Time'), + title: const Text('Select Preferred Time'), ), - body: PreferredTimeSelection()); + body: const PreferredTimeSelection()); } } class PreferredTimeSelection extends StatefulWidget { + const PreferredTimeSelection({super.key}); + @override _PreferredTimeSelectionState createState() => _PreferredTimeSelectionState(); } class _PreferredTimeSelectionState extends State { TimeOfDay _selectedTime = TimeOfDay.now(); - Loader _loader = Loader(); + final Loader _loader = Loader(); @override void initState() { @@ -82,7 +85,7 @@ class _PreferredTimeSelectionState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Padding( + const Padding( padding: EdgeInsets.all(20), child: Text( 'Select your preferred time to reflect back and improve. Your AI mentor will evaluate and provide feedback...', @@ -90,19 +93,19 @@ class _PreferredTimeSelectionState extends State { style: TextStyle(fontSize: 20), ), ), - Text( + const Text( 'Preferred Time:', style: TextStyle(fontSize: 20), ), - SizedBox(height: 10), + const SizedBox(height: 10), Text( - '${_selectedTime.format(context)}', - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + _selectedTime.format(context), + style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold), ), - SizedBox(height: 20), + const SizedBox(height: 20), ElevatedButton( onPressed: () => _selectTime(context), - child: Text('Select Time'), + child: const Text('Select Time'), ), ], ), diff --git a/lib/settings/settings_page.dart b/lib/settings/settings_page.dart index 13904d8..7af8a94 100644 --- a/lib/settings/settings_page.dart +++ b/lib/settings/settings_page.dart @@ -6,6 +6,7 @@ import '../setup/authentication_page.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'parent_mode.dart'; +import 'package:package_info_plus/package_info_plus.dart'; class SettingsPage extends StatefulWidget { const SettingsPage({Key? key}) : super(key: key); @@ -20,6 +21,7 @@ class _SettingsPageState extends State { final _loader = Loader(); final TextEditingController _serverurlController = TextEditingController(); + String _version = ''; void _saveSettings() async { if (_formKey.currentState!.validate()) { @@ -40,6 +42,10 @@ class _SettingsPageState extends State { void _loadSettings() async { _serverurlController.text = await _loader.loadserverurl(); + PackageInfo packageInfo = await PackageInfo.fromPlatform(); + setState(() { + _version = packageInfo.version; + }); } @override @@ -146,7 +152,7 @@ class _SettingsPageState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => EmailSettingsPage()), + builder: (context) => const EmailSettingsPage()), ); }, child: const Text("Parental controls")), @@ -242,8 +248,8 @@ class _SettingsPageState extends State { const SizedBox( height: 10, ), - const Center( - child: Text("Version 2.1.1", + Center( + child: Text("Version $_version.", style: TextStyle(fontSize: 18))), ], ), diff --git a/lib/setup/authentication_page.dart b/lib/setup/authentication_page.dart index 90c499d..ffa048e 100644 --- a/lib/setup/authentication_page.dart +++ b/lib/setup/authentication_page.dart @@ -54,7 +54,7 @@ class _EmailAuthState extends State { // The user account is already linked to the Google provider, so we can ignore this error } else { // An unexpected error occurred - throw e; + rethrow; } } } @@ -227,7 +227,7 @@ class _EmailAuthState extends State { const SizedBox( height: 60, ), - Align( + const Align( alignment: Alignment.centerLeft, child: Text("Email", style: TextStyle(fontSize: 24)), ), @@ -246,7 +246,7 @@ class _EmailAuthState extends State { ), ), const SizedBox(height: 40.0), - Align( + const Align( alignment: Alignment.centerLeft, child: Text("Password", style: TextStyle(fontSize: 24)), ), diff --git a/lib/setup/legal.dart b/lib/setup/legal.dart index 6cdd142..90e77bd 100644 --- a/lib/setup/legal.dart +++ b/lib/setup/legal.dart @@ -4,6 +4,8 @@ import 'package:url_launcher/url_launcher.dart'; import 'package:flutter/gestures.dart'; class PrivacyPolicy extends StatefulWidget { + const PrivacyPolicy({super.key}); + @override _PrivacyPolicyState createState() => _PrivacyPolicyState(); } @@ -13,10 +15,10 @@ class _PrivacyPolicyState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('Privacy Policy'), + title: const Text('Privacy Policy'), ), - body: Padding( - padding: const EdgeInsets.all(16.0), child: PrivacyPolicyWidget()), + body: const Padding( + padding: EdgeInsets.all(16.0), child: PrivacyPolicyWidget()), ); } } @@ -203,7 +205,7 @@ class _PrivacyPolicyWidgetState extends State { }); }, ), - Text('I agree to share the data'), + const Text('I agree to share the data'), Checkbox( value: _isTermsAccepted, onChanged: (bool? value) { @@ -247,7 +249,7 @@ class _PrivacyPolicyWidgetState extends State { Navigator.of(context).pop(); } : null, - child: Text('Continue'), + child: const Text('Continue'), ), ], ); diff --git a/lib/setup/setup_roller.dart b/lib/setup/setup_roller.dart index 346f087..479c497 100644 --- a/lib/setup/setup_roller.dart +++ b/lib/setup/setup_roller.dart @@ -1,11 +1,6 @@ import 'package:Mentor/settings/preferred_time.dart'; import 'package:flutter/material.dart'; -import '../settings/knowingthestudent.dart'; -import '../home/home_page.dart'; -import '../settings/apps_selection_page.dart'; -import '../settings/preferred_time.dart'; import 'package:introduction_screen/introduction_screen.dart'; -import 'package:flutter_html/flutter_html.dart'; class SetupPage extends StatefulWidget { const SetupPage({super.key}); @@ -22,7 +17,7 @@ class _SetupPageState extends State { pages: [ PageViewModel( title: 'Set your preferred time', - bodyWidget: PreferredTimeSelection(), + bodyWidget: const PreferredTimeSelection(), ), PageViewModel( title: 'How this works?', @@ -33,9 +28,9 @@ class _SetupPageState extends State { 'This app collects information from your phone and journal data, then sends it to our server. Our AI processes this data and uses books, research articles to provide you with the best content.We don\'t store any of the data on our servers except journal data. Everything else is stored on your phone locally.'), ], showNextButton: true, - next: Text("Next"), + next: const Text("Next"), showDoneButton: true, - done: Text("Done"), + done: const Text("Done"), onDone: () { Navigator.pushReplacementNamed(context, '/mentor'); }, diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 4607395..89275cc 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -14,6 +14,7 @@ import firebase_remote_config import flutter_local_notifications import flutter_secure_storage_macos import google_sign_in_ios +import package_info_plus import shared_preferences_foundation import url_launcher_macos @@ -27,6 +28,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) FLTGoogleSignInPlugin.register(with: registry.registrar(forPlugin: "FLTGoogleSignInPlugin")) + FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index c164c3b..041330b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -736,6 +736,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.10.0" + package_info_plus: + dependency: "direct main" + description: + name: package_info_plus + sha256: "88bc797f44a94814f2213db1c9bd5badebafdfb8290ca9f78d4b9ee2a3db4d79" + url: "https://pub.dev" + source: hosted + version: "5.0.1" + package_info_plus_platform_interface: + dependency: transitive + description: + name: package_info_plus_platform_interface + sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6" + url: "https://pub.dev" + source: hosted + version: "2.0.1" path: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 1f6587b..a3b54af 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # 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: 2.0.0+6 +version: 2.1.2+6 environment: sdk: '>=3.0.1 <4.0.0' @@ -59,7 +59,7 @@ dependencies: firebase_analytics: ^10.8.9 firebase_performance: ^0.9.3+17 firebase_remote_config: ^4.3.17 - + package_info_plus: ^5.0.1 dev_dependencies: flutter_test: sdk: flutter