diff --git a/lib/ChatBotPage.dart b/lib/ChatBotPage.dart new file mode 100644 index 0000000..878ac73 --- /dev/null +++ b/lib/ChatBotPage.dart @@ -0,0 +1,150 @@ +import 'package:flutter/material.dart'; +import 'package:google_generative_ai/google_generative_ai.dart'; + + +const apiKey = 'put-gemini-api-key'; + + +class ChatBotPage extends StatefulWidget { + const ChatBotPage({Key? key}) : super(key: key); + + + @override + _ChatBotPageState createState() => _ChatBotPageState(); +} + + +class _ChatBotPageState extends State { + final TextEditingController _controller = TextEditingController(); + final List> _messages = []; + GenerativeModel? _model; + + + @override + void initState() { + super.initState(); + _initializeModel(); + } + + + void _initializeModel() async { + _model = GenerativeModel( + model: 'gemini-1.5-flash-latest', + apiKey: apiKey, + ); + } + + + void _sendMessage() async { + if (_controller.text.isEmpty) return; + + + + + setState(() { + _messages.add({"sender": "user", "text": "${_controller.text}"}); + }); + + + final prompt = _controller.text + "don't give answer in markdown format"; + _controller.clear(); + + + if (_model != null) { + final content = [Content.text(prompt)]; + final response = await _model!.generateContent(content); + setState(() { + _messages.add({"sender": "bot", "text": response.text!}); + }); + } + } + + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('ChatBot'), + ), + body: Column( + children: [ + Expanded( + child: ListView.builder( + itemCount: _messages.length, + itemBuilder: (context, index) { + final message = _messages[index]; + final isUser = message["sender"] == "user"; + return Align( + alignment: isUser ? Alignment.centerRight : Alignment.centerLeft, + child: Container( + constraints: BoxConstraints( + maxWidth: MediaQuery.of(context).size.width * 0.75, + ), + margin: const EdgeInsets.symmetric(vertical: 5.0, horizontal: 10.0), + padding: const EdgeInsets.all(10.0), + decoration: BoxDecoration( + color: isUser ? Colors.blue[100] : Colors.grey[300], + borderRadius: BorderRadius.circular(10.0), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (!isUser) const CircleAvatar(child: Icon(Icons.android)), + if (!isUser) const SizedBox(width: 5.0), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(message["text"] ?? ''), + ], + ), + ), + if (isUser) const SizedBox(width: 5.0), + if (isUser) const CircleAvatar(child: Icon(Icons.person)), + ], + ), + ), + ); + }, + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + Expanded( + child: TextField( + controller: _controller, + decoration: const InputDecoration( + border: OutlineInputBorder(), + labelText: 'Enter your message', + ), + ), + ), + IconButton( + icon: const Icon(Icons.send), + onPressed: _sendMessage, + ), + ], + ), + ), + ], + ), + ); + } + + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } +} + + +void main() { + runApp(const MaterialApp( + home: ChatBotPage(), + )); +} + diff --git a/lib/home_page.dart b/lib/home_page.dart index 14a638e..62c226b 100644 --- a/lib/home_page.dart +++ b/lib/home_page.dart @@ -1,7 +1,10 @@ import 'dart:ui'; import 'package:flutter_screenutil/flutter_screenutil.dart'; + + import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:opso/ChatBotpage.dart'; import 'package:opso/opso_timeline.dart'; import 'package:opso/programs%20screen/girl_script.dart'; import 'package:opso/programs%20screen/google_season_of_docs_screen.dart'; @@ -18,23 +21,46 @@ import 'package:opso/widgets/book_mark_screen.dart'; import 'package:adaptive_theme/adaptive_theme.dart'; import 'package:opso/widgets/faq.dart'; import 'dart:math' as math; -import 'package:awesome_notifications/awesome_notifications.dart'; + + import 'about.dart'; + class HomePage extends StatefulWidget { const HomePage({super.key}); + @override State createState() => _HomePageState(); } + class _HomePageState extends State { @override void initState() { - // showNotification(); + showNotification(); super.initState(); + + _getInitialThemeMode(); + } + + + int _initialLabelIndex = 0; + void _getInitialThemeMode() async { + final savedThemeMode = await AdaptiveTheme.getThemeMode(); + setState(() { + if (savedThemeMode == AdaptiveThemeMode.light) { + _initialLabelIndex = 0; + } else if (savedThemeMode == AdaptiveThemeMode.dark) { + _initialLabelIndex = 1; + } else { + _initialLabelIndex = 0; + } + }); + } + //show various notification from here void showNotification() async { await NotificationService.showNotification( @@ -43,6 +69,7 @@ class _HomePageState extends State { ); } + //used to show the notification every 5 ms void showScheduleNotification() async { await NotificationService.showNotification( @@ -52,6 +79,7 @@ class _HomePageState extends State { interval: 5); } + final List programs = [ Program( title: 'Google Summer of Code', @@ -95,6 +123,7 @@ class _HomePageState extends State { ), ]; + @override Widget build(BuildContext context) { // var media = MediaQuery.of(context).size; @@ -102,6 +131,7 @@ class _HomePageState extends State { ? Colors.black.withOpacity(0.6) // Example dark mode color : Colors.white.withOpacity(0.6); // Example light mode color + ScreenUtil.init( context, ); @@ -113,7 +143,7 @@ class _HomePageState extends State { title: Text( 'OpSo', style: - TextStyle(fontWeight: FontWeight.bold, fontSize: appBarFontSize), + TextStyle(fontWeight: FontWeight.bold, fontSize: appBarFontSize), ), actions: [ IconButton( @@ -123,14 +153,25 @@ class _HomePageState extends State { }, ), /*IconButton( - icon: Icon(Icons.menu), - onPressed: () { - // Open drawer when the menu icon is clicked - Scaffold.of(context).openDrawer(); - }, - ),*/ + icon: Icon(Icons.menu), + onPressed: () { + // Open drawer when the menu icon is clicked + Scaffold.of(context).openDrawer(); + }, + ),*/ ], ), + floatingActionButton: FloatingActionButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const ChatBotPage(), + ), + ); + }, + child: const Icon(Icons.chat_bubble_outline), + ), drawer: Drawer( backgroundColor: Colors.transparent, width: MediaQuery.of(context).size.width, @@ -148,7 +189,7 @@ class _HomePageState extends State { child: SafeArea( child: Padding( padding: - const EdgeInsets.only(left: 30, right: 30, top: 30), + const EdgeInsets.only(left: 30, right: 30, top: 30), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -211,7 +252,7 @@ class _HomePageState extends State { context, MaterialPageRoute( builder: (context) => - const BookMarkScreen())); + const BookMarkScreen())); }, ), const SizedBox(height: 15), @@ -228,7 +269,7 @@ class _HomePageState extends State { context, MaterialPageRoute( builder: (context) => - const OpsoTimeLineScreen(), + const OpsoTimeLineScreen(), ), ); }, @@ -242,7 +283,8 @@ class _HomePageState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => FAQPage(), + builder: (context) => + FAQPage(), ), ); }, @@ -250,7 +292,7 @@ class _HomePageState extends State { SizedBox(height: ScreenUtil().setHeight(15)), ListTile( leading: - const Icon(FontAwesomeIcons.circleInfo), + const Icon(FontAwesomeIcons.circleInfo), title: const Text('About'), onTap: () { Navigator.push( @@ -296,6 +338,7 @@ class _HomePageState extends State { ); } + void navigateToScreen(BuildContext context, Program program) { switch (program.title) { case 'Google Summer of Code': @@ -307,6 +350,7 @@ class _HomePageState extends State { ); break; + case 'Google Season of Docs': Navigator.push( context, @@ -316,6 +360,7 @@ class _HomePageState extends State { ); break; + case 'Major League Hacking Fellowship': Navigator.push( context, @@ -324,6 +369,7 @@ class _HomePageState extends State { ); break; + case 'GirlScript Summer of Code': Navigator.push( context, @@ -333,6 +379,7 @@ class _HomePageState extends State { ); break; + case 'Social Winter of Code': Navigator.push( context, @@ -351,14 +398,17 @@ class _HomePageState extends State { ); break; + case 'Outreachy': Navigator.push(context, MaterialPageRoute(builder: (context) => const OutReachy())); + case 'Summer of Bitcoin': Navigator.pushNamed(context, "/summer_of_bitcoin"); case 'Open Summer of Code': + Navigator.push( context, MaterialPageRoute( @@ -366,6 +416,7 @@ class _HomePageState extends State { ), ); + case 'Linux Foundation': Navigator.push(context, MaterialPageRoute(builder: (context) => const LinuxFoundation())); @@ -376,11 +427,13 @@ class _HomePageState extends State { } } + class ProgramOption extends StatelessWidget { final String title; final String imageAssetPath; final VoidCallback onTap; + const ProgramOption({ super.key, required this.title, @@ -388,6 +441,7 @@ class ProgramOption extends StatelessWidget { required this.onTap, }); + @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; @@ -434,6 +488,7 @@ class ProgramOption extends StatelessWidget { } } + class ProgramSearchDelegate extends SearchDelegate { final List programs = [ Program( @@ -478,6 +533,7 @@ class ProgramSearchDelegate extends SearchDelegate { ), ]; + @override List buildActions(BuildContext context) { return [ @@ -490,6 +546,7 @@ class ProgramSearchDelegate extends SearchDelegate { ]; } + @override Widget buildLeading(BuildContext context) { return IconButton( @@ -500,20 +557,23 @@ class ProgramSearchDelegate extends SearchDelegate { ); } + @override Widget buildResults(BuildContext context) { return Container(); } + @override Widget buildSuggestions(BuildContext context) { final List suggestionList = query.isEmpty ? [] : programs - .where((program) => - program.title.toLowerCase().contains(query.toLowerCase())) - .map((program) => program.title) - .toList(); + .where((program) => + program.title.toLowerCase().contains(query.toLowerCase())) + .map((program) => program.title) + .toList(); + return ListView.builder( itemCount: suggestionList.length, @@ -526,9 +586,10 @@ class ProgramSearchDelegate extends SearchDelegate { ); } + void navigateToScreen(BuildContext context, String title) { final Program selectedProgram = - programs.firstWhere((program) => program.title == title); + programs.firstWhere((program) => program.title == title); switch (selectedProgram.title) { case 'Google Summer of Code': Navigator.push( @@ -547,6 +608,7 @@ class ProgramSearchDelegate extends SearchDelegate { ); break; + case 'Major League Hacking Fellowship': Navigator.push( context, @@ -556,6 +618,7 @@ class ProgramSearchDelegate extends SearchDelegate { ); break; + case 'GirlScript Summer of Code': Navigator.push( context, @@ -565,6 +628,7 @@ class ProgramSearchDelegate extends SearchDelegate { ); break; + case 'Social Winter of Code': Navigator.push( context, @@ -583,23 +647,28 @@ class ProgramSearchDelegate extends SearchDelegate { ); break; + case 'Linux Foundation': Navigator.push(context, MaterialPageRoute(builder: (context) => const LinuxFoundation())); break; + default: break; } } } + class Program { final String title; final String imageAssetPath; + Program({ required this.title, required this.imageAssetPath, }); } + diff --git a/pubspec.lock b/pubspec.lock index ca60b7e..dc98038 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -208,6 +208,14 @@ packages: url: "https://pub.dev" source: hosted version: "10.7.0" + google_generative_ai: + dependency: "direct main" + description: + name: google_generative_ai + sha256: "76e35d93b8c1cd888f69a1a371f8c5dc54cec372b6c74a4c0a5d506e7cf82c1a" + url: "https://pub.dev" + source: hosted + version: "0.4.3" html: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 32c58df..5baa0e2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -36,6 +36,7 @@ dependencies: http: ^1.2.1 url_launcher: ^6.2.6 shared_preferences: ^2.0.11 + google_generative_ai: ^0.4.3 dio: ^5.4.3+1 animated_text_kit: ^4.2.2 adaptive_theme: ^3.6.0