diff --git a/login/assets/images/login_frame.png b/login/assets/images/login_frame.png
new file mode 100644
index 0000000..c9f35cf
Binary files /dev/null and b/login/assets/images/login_frame.png differ
diff --git a/login/assets/images/login_frame.svg b/login/assets/images/login_frame.svg
new file mode 100644
index 0000000..46443a6
--- /dev/null
+++ b/login/assets/images/login_frame.svg
@@ -0,0 +1,25 @@
+
diff --git a/login/lib/api/apis.dart b/login/lib/api/apis.dart
index 3bef2ff..5f497fb 100644
--- a/login/lib/api/apis.dart
+++ b/login/lib/api/apis.dart
@@ -1,10 +1,13 @@
// ignore_for_file: avoid_print
+import 'dart:convert';
import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
+import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:firebase_storage/firebase_storage.dart';
+import 'package:http/http.dart';
import 'package:login/model/chat_user_model.dart';
import 'package:login/model/messages.dart';
@@ -23,6 +26,58 @@ class APIs {
//for returning current user
static User get user => auth.currentUser!;
+ // for accessing firebase messaging (Push Notification)
+ static FirebaseMessaging fMessaging = FirebaseMessaging.instance;
+
+ // for getting firebase messaging token
+ static Future getFirebaseMessagingToken() async {
+ await fMessaging.getToken().then((t) {
+ if (t != null) {
+ me.PushToken = t;
+ print('Push Token: $t');
+ }
+ });
+
+ // for handling foreground messages
+ FirebaseMessaging.onMessage.listen((RemoteMessage message) {
+ print('Got a message whilst in the foreground!');
+ print('Message data: ${message.data}');
+
+ if (message.notification != null) {
+ print('Message also contained a notification: ${message.notification}');
+ }
+ });
+ }
+
+ // for sending push notification
+ static Future sendPushNotification(
+ ChatUser chatUser, String msg) async {
+ try {
+ final body = {
+ "to": chatUser.PushToken,
+ "notification": {
+ "title": me.Name, //our name should be send
+ "body": msg,
+ },
+ // "data": {
+ // "some_data": "User ID: ${me.id}",
+ // },
+ };
+
+ var res = await post(Uri.parse('https://fcm.googleapis.com/fcm/send'),
+ headers: {
+ HttpHeaders.contentTypeHeader: 'application/json',
+ HttpHeaders.authorizationHeader:
+ 'key=AAAAJoFEO6I:APA91bElgw77iGQYJdEov_3ea5i3j6_vpjpPm7q4D4xahUmOPny_4W9g3Vus_FgrldMScGNcd7qn46lko8wTYsX-yZQsJhRrKaj5T_NV3TkJ8vLkMIxxkSKLuz2mwbNelOCo-t7ma-3N'
+ },
+ body: jsonEncode(body));
+ print('Response status: ${res.statusCode}');
+ print('Response body: ${res.body}');
+ } catch (e) {
+ print('\nsendPushNotificationE: $e');
+ }
+ }
+
//for checking if user exists or not??
static Future userExists() async {
return (await firestore.collection('Users').doc(user.uid).get()).exists;
@@ -33,6 +88,9 @@ class APIs {
await firestore.collection('Users').doc(user.uid).get().then((user) async {
if (user.exists) {
me = ChatUser.fromJson(user.data()!);
+ await getFirebaseMessagingToken();
+
+ APIs.updateActiveStatus(true);
} else {
await createUser().then((value) => getSelfInfo());
}
@@ -119,6 +177,27 @@ class APIs {
.snapshots();
}
+ // // for sending message
+ // static Future sendMessage(
+ // ChatUser chatUser, String msg, Type type) async {
+ // //message sending time (also used as id)
+ // final time = DateTime.now().millisecondsSinceEpoch.toString();
+
+ // //message to send
+ // final Message message = Message(
+ // toId: chatUser.Id,
+ // msg: msg,
+ // read: '',
+ // type: type,
+ // fromId: user.uid,
+ // sent: time);
+
+ // final ref = firestore
+ // .collection('chats/${getConversationID(chatUser.Id)}/messages/');
+ // await ref.doc(time).set(message.toJson()).then((value) =>
+ // sendPushNotification(chatUser, type == Type.text ? msg : 'image'));
+ // }
+
// for sending message
static Future sendMessage(
ChatUser chatUser,
@@ -139,7 +218,8 @@ class APIs {
final ref = firestore
.collection('chats/${getConversationID(chatUser.Id)}/messages/');
- await ref.doc(time).set(message.toJson());
+ await ref.doc(time).set(message.toJson()).then((value) =>
+ sendPushNotification(chatUser, type == Type.text ? msg : 'image'));;
}
//update read status of message
diff --git a/login/lib/auth/loginscreen.dart b/login/lib/auth/loginscreen.dart
index b75f07f..f77f62b 100644
--- a/login/lib/auth/loginscreen.dart
+++ b/login/lib/auth/loginscreen.dart
@@ -2,9 +2,11 @@
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:login/api/apis.dart';
import 'package:login/auth/firebase_auth_servies.dart';
import 'package:login/auth/signuppage.dart';
+import 'package:login/main.dart';
import 'package:login/screens/homescreen.dart';
class LoginPage extends StatefulWidget {
@@ -34,75 +36,165 @@ class _LoginPageState extends State {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
- title: const Text('Login Page'),
- ),
- body: Padding(
- padding: const EdgeInsets.all(16.0),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- TextField(
- controller: emailController,
- keyboardType: TextInputType.emailAddress,
- decoration: const InputDecoration(
- labelText: 'Email',
- border: OutlineInputBorder(),
+ backgroundColor: Colors.transparent,
+ title: Center(
+ child: Column(
+ children: [
+ Text(
+ "Login",
+ style: TextStyle(
+ fontSize: 22.sp,
+ fontWeight: FontWeight.w600,
+ color: Colors.white),
),
- ),
- const SizedBox(height: 16.0),
- TextField(
- controller: passwordController,
- obscureText: true,
- decoration: const InputDecoration(
- labelText: 'Password',
- border: OutlineInputBorder(),
+ Text(
+ "Enter Email Password to continue",
+ style: TextStyle(
+ fontSize: 16.sp,
+ fontWeight: FontWeight.w300,
+ color: Colors.white),
),
- ),
- const SizedBox(height: 32.0),
- isSignIn
- ? const CircularProgressIndicator(
- color: Colors.black,
- )
- : ElevatedButton(
- onPressed: () {
- print('Email: ${emailController.text}');
- print('Password: ${passwordController.text}');
- _signIn();
- APIs.updateActiveStatus(true);
- },
- child: const Text('Login'),
- ),
- InkWell(
- onTap: () {
- //
- },
- child: const Row(
- mainAxisAlignment: MainAxisAlignment.center,
+ ],
+ ),
+ ),
+ ),
+ extendBodyBehindAppBar: true,
+ body: Container(
+ decoration: const BoxDecoration(
+ //gradient: LinearGradient(colors: Colors.white ),
+ gradient: LinearGradient(
+ begin: Alignment.topLeft,
+ end: Alignment.bottomRight,
+ colors: [
+ Color.fromRGBO(0, 248, 248, 1),
+ Color.fromRGBO(0, 57, 89, 1),
+ ],
+ ),
+ ),
+ child: Stack(children: [
+ //for showing the robot background image
+ Align(
+ alignment: Alignment.topCenter,
+ child: Image.asset("assets/images/login_frame.png"),
+ ),
+ Positioned(
+ bottom: 0,
+ child: Column(
children: [
- Icon(Icons.account_circle),
- Text("Sign in with Google "),
+ 20.verticalSpace,
+ SizedBox(
+ width: mq.width * 1,
+ child: Column(
+ children: [
+ Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ 20.verticalSpace,
+ TextField(
+ controller: emailController,
+ keyboardType: TextInputType.emailAddress,
+ style: const TextStyle(
+ color:
+ Colors.white, // Change text color to blue
+ ),
+ decoration: InputDecoration(
+ labelText: 'Email',
+ labelStyle: TextStyle(
+ fontSize: 16.sp,
+ fontWeight: FontWeight.w300,
+ color: Colors.white,
+ ),
+ border: const OutlineInputBorder(),
+ ),
+ ),
+ 15.verticalSpace,
+ TextField(
+ controller: passwordController,
+ obscureText: true,
+ style: const TextStyle(
+ color:
+ Colors.white, // Change text color to blue
+ ),
+ decoration: InputDecoration(
+ labelText: 'Password',
+ labelStyle: TextStyle(
+ fontSize: 16.sp,
+ fontWeight: FontWeight.w300,
+ color: Colors.white,
+ ),
+ border: const OutlineInputBorder(),
+ ),
+ ),
+ const SizedBox(height: 32.0),
+ isSignIn
+ ? const CircularProgressIndicator(
+ color: Colors.black,
+ )
+ : ElevatedButton.icon(
+ icon: const Icon(Icons.login,
+ color: Colors.white),
+ onPressed: () {
+ print('Email: ${emailController.text}');
+ print(
+ 'Password: ${passwordController.text}');
+ _signIn();
+
+ },
+ label: Text(
+ "Login",
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 20.sp,
+ ),
+ ),
+ style: ButtonStyle(
+ backgroundColor:
+ MaterialStateProperty.all(
+ Colors.blueAccent),
+ // Change the color here
+ ),
+ ),
+ InkWell(
+ onTap: () {
+ //
+ },
+ child: const Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Icon(Icons.account_circle),
+ Text("Sign in with Google "),
+ ],
+ ),
+ ),
+ const SizedBox(
+ height: 30,
+ ),
+ Row(
+ children: [
+ const Text("New User?"),
+ TextButton(
+ onPressed: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) =>
+ const SignUpPage()),
+ );
+ },
+ child: const Text("Sign up"))
+ ],
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ )
],
- ),
- ),
- const SizedBox(
- height: 30,
- ),
- Row(
- children: [
- const Text("New User?"),
- TextButton(
- onPressed: () {
- Navigator.push(
- context,
- MaterialPageRoute(
- builder: (context) => const SignUpPage()),
- );
- },
- child: const Text("Sign up"))
- ],
- ),
- ],
- ),
+ )),
+ ]),
),
);
}
diff --git a/login/lib/auth/signuppage.dart b/login/lib/auth/signuppage.dart
index 207fb3c..e60615a 100644
--- a/login/lib/auth/signuppage.dart
+++ b/login/lib/auth/signuppage.dart
@@ -32,100 +32,125 @@ class _SignUpPageState extends State {
@override
Widget build(BuildContext context) {
return Scaffold(
+ extendBodyBehindAppBar: true,
appBar: AppBar(
automaticallyImplyLeading: false,
title: const Text("SignUp"),
),
- body: Center(
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 15),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- const Text(
- "Sign Up",
- style: TextStyle(fontSize: 27, fontWeight: FontWeight.bold),
- ),
- const SizedBox(
- height: 30,
- ),
- FormContainerWidget(
- controller: _usernameController,
- hintText: "Username",
- isPasswordField: false,
- ),
- const SizedBox(
- height: 10,
- ),
- FormContainerWidget(
- controller: _emailController,
- hintText: "Email",
- isPasswordField: false,
- ),
- const SizedBox(
- height: 10,
- ),
- FormContainerWidget(
- controller: _passwordController,
- hintText: "Password",
- isPasswordField: true,
- ),
- const SizedBox(
- height: 30,
- ),
- GestureDetector(
- onTap: () {
- _signUp();
- },
- child: Container(
- width: double.infinity,
- height: 45,
- decoration: BoxDecoration(
- color: Colors.blue,
- borderRadius: BorderRadius.circular(10),
- ),
- child: Center(
- child: isSigningUp
- ? const CircularProgressIndicator(
- color: Colors.white,
- )
- : const Text(
- "Sign Up",
- style: TextStyle(
- color: Colors.white,
- fontWeight: FontWeight.bold),
- )),
+ body: Column(children: [
+ Center(
+ child: Align(
+ alignment: Alignment.topCenter,
+ child: Container(
+ decoration: const BoxDecoration(
+ //gradient: LinearGradient(colors: Colors.white ),
+ gradient: LinearGradient(
+ begin: Alignment.topLeft,
+ end: Alignment.bottomRight,
+ colors: [
+ Color.fromRGBO(0, 248, 248, 1),
+ Color.fromRGBO(0, 57, 89, 1),
+ ],
+ ),
+ image: DecorationImage(
+ image: AssetImage("assets/images/login_frame.png"),
+ fit: BoxFit.cover,
),
),
- const SizedBox(
- height: 20,
- ),
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- const Text("Already have an account?"),
- const SizedBox(
- width: 5,
+ ),
+ ),
+ ),
+ Center(
+ child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 15),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ const Text(
+ "Sign Up",
+ style: TextStyle(fontSize: 27, fontWeight: FontWeight.bold),
+ ),
+ const SizedBox(
+ height: 30,
+ ),
+ FormContainerWidget(
+ controller: _usernameController,
+ hintText: "Username",
+ isPasswordField: false,
+ ),
+ const SizedBox(
+ height: 10,
+ ),
+ FormContainerWidget(
+ controller: _emailController,
+ hintText: "Email",
+ isPasswordField: false,
+ ),
+ const SizedBox(
+ height: 10,
+ ),
+ FormContainerWidget(
+ controller: _passwordController,
+ hintText: "Password",
+ isPasswordField: true,
+ ),
+ const SizedBox(
+ height: 30,
+ ),
+ GestureDetector(
+ onTap: () {
+ _signUp();
+ },
+ child: Container(
+ width: double.infinity,
+ height: 45,
+ decoration: BoxDecoration(
+ color: Colors.blue,
+ borderRadius: BorderRadius.circular(10),
+ ),
+ child: Center(
+ child: isSigningUp
+ ? const CircularProgressIndicator(
+ color: Colors.white,
+ )
+ : const Text(
+ "Sign Up",
+ style: TextStyle(
+ color: Colors.white,
+ fontWeight: FontWeight.bold),
+ )),
),
- GestureDetector(
- onTap: () {
- Navigator.pushAndRemoveUntil(
- context,
- MaterialPageRoute(
- builder: (context) => const LoginPage()),
- (route) => false);
- },
- child: const Text(
- "Login",
- style: TextStyle(
- color: Colors.blue, fontWeight: FontWeight.bold),
- ))
- ],
- )
- ],
+ ),
+ const SizedBox(
+ height: 20,
+ ),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ const Text("Already have an account?"),
+ const SizedBox(
+ width: 5,
+ ),
+ GestureDetector(
+ onTap: () {
+ Navigator.pushAndRemoveUntil(
+ context,
+ MaterialPageRoute(
+ builder: (context) => const LoginPage()),
+ (route) => false);
+ },
+ child: const Text(
+ "Login",
+ style: TextStyle(
+ color: Colors.blue, fontWeight: FontWeight.bold),
+ ))
+ ],
+ )
+ ],
+ ),
),
),
- ),
+ ]),
);
}
diff --git a/login/lib/dialogs/profile_dialog.dart b/login/lib/dialogs/profile_dialog.dart
index 8c44185..b1d12ea 100644
--- a/login/lib/dialogs/profile_dialog.dart
+++ b/login/lib/dialogs/profile_dialog.dart
@@ -17,7 +17,7 @@ class ProfileDialog extends StatelessWidget {
Widget build(BuildContext context) {
return AlertDialog(
contentPadding: EdgeInsets.zero,
- backgroundColor: Colors.white.withOpacity(.9),
+ backgroundColor: const Color.fromRGBO(0, 163, 255, 1),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
@@ -35,10 +35,10 @@ class ProfileDialog extends StatelessWidget {
child: Text(
user.Name,
overflow: TextOverflow.ellipsis,
- style: const TextStyle(
- fontSize: 18,
- fontWeight: FontWeight.w500,
- ),
+ style: TextStyle(
+ fontSize: 18.sp,
+ fontWeight: FontWeight.w500,
+ color: Colors.white),
),
),
@@ -60,7 +60,7 @@ class ProfileDialog extends StatelessWidget {
padding: const EdgeInsets.all(0),
shape: const CircleBorder(),
child: const Icon(Icons.info_outline,
- color: Colors.blue, size: 30),
+ color: Colors.white, size: 30),
),
],
),
diff --git a/login/lib/main.dart b/login/lib/main.dart
index 3cde35a..3fdb2bb 100644
--- a/login/lib/main.dart
+++ b/login/lib/main.dart
@@ -1,3 +1,4 @@
+import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
@@ -10,15 +11,27 @@ import 'firebase_options.dart';
// global object for accessing device screen size
late Size mq;
-void main() {
+Future main() async {
WidgetsFlutterBinding.ensureInitialized();
- _initialiseFirebase();
+ await _initialiseFirebase();
runApp(const MyApp());
}
-class MyApp extends StatelessWidget {
+class MyApp extends StatefulWidget {
const MyApp({super.key});
+ @override
+ State createState() => _MyAppState();
+}
+
+class _MyAppState extends State {
+ static FirebaseMessaging fMessaging = FirebaseMessaging.instance;
+ @override
+ void initState() {
+ super.initState();
+ fMessaging.requestPermission();
+ }
+
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
diff --git a/login/lib/model/ai_message_model.dart b/login/lib/model/ai_message_model.dart
new file mode 100644
index 0000000..76b5af3
--- /dev/null
+++ b/login/lib/model/ai_message_model.dart
@@ -0,0 +1,5 @@
+class AIMessage {
+ bool isSender;
+ String msg;
+ AIMessage(this.isSender, this.msg);
+}
diff --git a/login/lib/screens/chat_screen.dart b/login/lib/screens/chat_screen.dart
index ef06dd4..28a8fe2 100644
--- a/login/lib/screens/chat_screen.dart
+++ b/login/lib/screens/chat_screen.dart
@@ -1,165 +1,165 @@
-// import 'dart:convert';
-// import 'package:chat_bubbles/bubbles/bubble_normal.dart';
-// import 'package:flutter/material.dart';
-// import 'package:http/http.dart' as http;
-// import 'package:login/widgets/message.dart';
+import 'dart:convert';
+import 'package:chat_bubbles/bubbles/bubble_normal.dart';
+import 'package:flutter/material.dart';
+import 'package:http/http.dart' as http;
+import 'package:login/model/ai_message_model.dart';
-// class ChatScreen extends StatefulWidget {
-// const ChatScreen({super.key});
+class AIChatScreen extends StatefulWidget {
+ const AIChatScreen({super.key});
-// @override
-// State createState() => _ChatScreenState();
-// }
+ @override
+ State createState() => _AIChatScreenState();
+}
-// class _ChatScreenState extends State {
-// TextEditingController controller = TextEditingController();
-// ScrollController scrollController = ScrollController();
-// List msgs = [];
-// bool isTyping = false;
+class _AIChatScreenState extends State {
+ TextEditingController controller = TextEditingController();
+ ScrollController scrollController = ScrollController();
+ List msgs = [];
+ bool isTyping = false;
-// void sendMsg() async {
-// String text = controller.text;
-// String apiKey = "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";
-// controller.clear();
-// try {
-// if (text.isNotEmpty) {
-// setState(() {
-// msgs.insert(0, Message(true, text));
-// isTyping = true;
-// });
-// scrollController.animateTo(0.0,
-// duration: const Duration(seconds: 1), curve: Curves.easeOut);
-// var response = await http.post(
-// Uri.parse("https://api.openai.com/v1/chat/completions"),
-// headers: {
-// "Authorization": "Bearer $apiKey",
-// "Content-Type": "application/json"
-// },
-// body: jsonEncode({
-// "model": "gpt-3.5-turbo",
-// "messages": [
-// {"role": "user", "content": text}
-// ]
-// }));
-// if (response.statusCode == 200) {
-// var json = jsonDecode(response.body);
-// setState(() {
-// isTyping = false;
-// msgs.insert(
-// 0,
-// Message(
-// false,
-// json["choices"][0]["message"]["content"]
-// .toString()
-// .trimLeft()));
-// });
-// scrollController.animateTo(0.0,
-// duration: const Duration(seconds: 1), curve: Curves.easeOut);
-// }
-// }
-// } on Exception {
-// // ignore: use_build_context_synchronously
-// ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
-// content: Text("Some error occurred, please try again!")));
-// }
-// }
+ void sendMsg() async {
+ String text = controller.text;
+ String apiKey = "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";
+ controller.clear();
+ try {
+ if (text.isNotEmpty) {
+ setState(() {
+ msgs.insert(0, AIMessage(true, text));
+ isTyping = true;
+ });
+ scrollController.animateTo(0.0,
+ duration: const Duration(seconds: 1), curve: Curves.easeOut);
+ var response = await http.post(
+ Uri.parse("https://api.openai.com/v1/chat/completions"),
+ headers: {
+ "Authorization": "Bearer $apiKey",
+ "Content-Type": "application/json"
+ },
+ body: jsonEncode({
+ "model": "gpt-3.5-turbo",
+ "messages": [
+ {"role": "user", "content": text}
+ ]
+ }));
+ if (response.statusCode == 200) {
+ var json = jsonDecode(response.body);
+ setState(() {
+ isTyping = false;
+ msgs.insert(
+ 0,
+ AIMessage(
+ false,
+ json["choices"][0]["message"]["content"]
+ .toString()
+ .trimLeft()));
+ });
+ scrollController.animateTo(0.0,
+ duration: const Duration(seconds: 1), curve: Curves.easeOut);
+ }
+ }
+ } on Exception {
+ // ignore: use_build_context_synchronously
+ ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
+ content: Text("Some error occurred, please try again!")));
+ }
+ }
-// @override
-// Widget build(BuildContext context) {
-// return Scaffold(
-// appBar: AppBar(
-// title: const Text("Chat Bot"),
-// ),
-// body: Column(
-// children: [
-// const SizedBox(
-// height: 8,
-// ),
-// Expanded(
-// child: ListView.builder(
-// controller: scrollController,
-// itemCount: msgs.length,
-// shrinkWrap: true,
-// reverse: true,
-// itemBuilder: (context, index) {
-// return Padding(
-// padding: const EdgeInsets.symmetric(vertical: 4),
-// child: isTyping && index == 0
-// ? Column(
-// children: [
-// BubbleNormal(
-// text: msgs[0].msg,
-// isSender: true,
-// color: Colors.blue.shade100,
-// ),
-// const Padding(
-// padding: EdgeInsets.only(left: 16, top: 4),
-// child: Align(
-// alignment: Alignment.centerLeft,
-// child: Text("Typing...")),
-// )
-// ],
-// )
-// : BubbleNormal(
-// text: msgs[index].msg,
-// isSender: msgs[index].isSender,
-// color: msgs[index].isSender
-// ? Colors.blue.shade100
-// : Colors.grey.shade200,
-// ));
-// }),
-// ),
-// Row(
-// children: [
-// Expanded(
-// child: Padding(
-// padding: const EdgeInsets.all(8.0),
-// child: Container(
-// width: double.infinity,
-// height: 40,
-// decoration: BoxDecoration(
-// color: Colors.grey[200],
-// borderRadius: BorderRadius.circular(10)),
-// child: Padding(
-// padding: const EdgeInsets.symmetric(horizontal: 8),
-// child: TextField(
-// controller: controller,
-// textCapitalization: TextCapitalization.sentences,
-// onSubmitted: (value) {
-// sendMsg();
-// },
-// textInputAction: TextInputAction.send,
-// showCursor: true,
-// decoration: const InputDecoration(
-// border: InputBorder.none, hintText: "Enter text"),
-// ),
-// ),
-// ),
-// ),
-// ),
-// InkWell(
-// onTap: () {
-// sendMsg();
-// },
-// child: Container(
-// height: 40,
-// width: 40,
-// decoration: BoxDecoration(
-// color: Colors.blue,
-// borderRadius: BorderRadius.circular(30)),
-// child: const Icon(
-// Icons.send,
-// color: Colors.white,
-// ),
-// ),
-// ),
-// const SizedBox(
-// width: 8,
-// )
-// ],
-// ),
-// ],
-// ),
-// );
-// }
-// }
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: const Text("Chat Bot"),
+ ),
+ body: Column(
+ children: [
+ const SizedBox(
+ height: 8,
+ ),
+ Expanded(
+ child: ListView.builder(
+ controller: scrollController,
+ itemCount: msgs.length,
+ shrinkWrap: true,
+ reverse: true,
+ itemBuilder: (context, index) {
+ return Padding(
+ padding: const EdgeInsets.symmetric(vertical: 4),
+ child: isTyping && index == 0
+ ? Column(
+ children: [
+ BubbleNormal(
+ text: msgs[0].msg,
+ isSender: true,
+ color: Colors.blue.shade100,
+ ),
+ const Padding(
+ padding: EdgeInsets.only(left: 16, top: 4),
+ child: Align(
+ alignment: Alignment.centerLeft,
+ child: Text("Typing...")),
+ )
+ ],
+ )
+ : BubbleNormal(
+ text: msgs[index].msg,
+ isSender: msgs[index].isSender,
+ color: msgs[index].isSender
+ ? Colors.blue.shade100
+ : Colors.grey.shade200,
+ ));
+ }),
+ ),
+ Row(
+ children: [
+ Expanded(
+ child: Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Container(
+ width: double.infinity,
+ height: 40,
+ decoration: BoxDecoration(
+ color: Colors.grey[200],
+ borderRadius: BorderRadius.circular(10)),
+ child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 8),
+ child: TextField(
+ controller: controller,
+ textCapitalization: TextCapitalization.sentences,
+ onSubmitted: (value) {
+ sendMsg();
+ },
+ textInputAction: TextInputAction.send,
+ showCursor: true,
+ decoration: const InputDecoration(
+ border: InputBorder.none, hintText: "Enter text"),
+ ),
+ ),
+ ),
+ ),
+ ),
+ InkWell(
+ onTap: () {
+ sendMsg();
+ },
+ child: Container(
+ height: 40,
+ width: 40,
+ decoration: BoxDecoration(
+ color: Colors.blue,
+ borderRadius: BorderRadius.circular(30)),
+ child: const Icon(
+ Icons.send,
+ color: Colors.white,
+ ),
+ ),
+ ),
+ const SizedBox(
+ width: 8,
+ )
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/login/lib/screens/homescreen.dart b/login/lib/screens/homescreen.dart
index 9ac5703..6ad01fa 100644
--- a/login/lib/screens/homescreen.dart
+++ b/login/lib/screens/homescreen.dart
@@ -7,6 +7,7 @@ import 'package:login/model/chat_user_model.dart';
import 'package:login/screens/contact_list.dart';
import 'package:login/screens/profile_screen.dart';
import 'package:login/widgets/chat_user_card.dart';
+import 'package:login/widgets/custom_bottom_navighationbar.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@@ -16,6 +17,14 @@ class HomePage extends StatefulWidget {
}
class _HomePageState extends State {
+ int _currentIndex = 0;
+
+ void _onTabSelected(int index) {
+ setState(() {
+ _currentIndex = index;
+ });
+ }
+
List _list = [];
final List _searchlist = [];
bool _isSearching = false;
@@ -74,7 +83,7 @@ class _HomePageState extends State {
],
),
floatingActionButton: FloatingActionButton(
- backgroundColor: Colors.lightBlue,
+ backgroundColor: const Color.fromRGBO(0, 163, 255, 1),
onPressed: () {
Navigator.push(
context,
@@ -88,45 +97,62 @@ class _HomePageState extends State {
color: Colors.white,
),
),
- body: StreamBuilder(
- stream: APIs.getAllUsers(),
- builder: (context, snapshot) {
- switch (snapshot.connectionState) {
- // if data s loading
- case ConnectionState.waiting:
- case ConnectionState.none:
- return const Center(
- child: CircularProgressIndicator(),
- );
-
- //if some or all data is loaded then show it
- case ConnectionState.active:
- case ConnectionState.done:
- final data = snapshot.data?.docs;
- _list =
- data?.map((e) => ChatUser.fromJson(e.data())).toList() ?? [];
-
- if (_list.isNotEmpty) {
- return ListView.builder(
- itemCount: _list.length, // Use the length of the list
- padding: EdgeInsets.only(top: mq.height * .01),
- physics: const BouncingScrollPhysics(),
- itemBuilder: (context, index) {
- //return Text('Name: ${list[index]}');
- return ChatUserCard(user: _list[index]);
- },
- );
- } else {
+ body: Container(
+ decoration: const BoxDecoration(
+ //gradient: LinearGradient(colors: Colors.white ),
+ gradient: LinearGradient(
+ begin: Alignment.topLeft,
+ end: Alignment.bottomRight,
+ colors: [
+ Color.fromRGBO(0, 248, 248, 1),
+ Color.fromRGBO(0, 57, 89, 1),
+ ],
+ ),
+ ),
+ child: StreamBuilder(
+ stream: APIs.getAllUsers(),
+ builder: (context, snapshot) {
+ switch (snapshot.connectionState) {
+ // if data s loading
+ case ConnectionState.waiting:
+ case ConnectionState.none:
return const Center(
- child: Text(
- "No Connections Found...",
- textAlign: TextAlign.center,
- style: TextStyle(fontSize: 16),
- ),
+ child: CircularProgressIndicator(),
);
- }
- }
- },
+
+ //if some or all data is loaded then show it
+ case ConnectionState.active:
+ case ConnectionState.done:
+ final data = snapshot.data?.docs;
+ _list =
+ data?.map((e) => ChatUser.fromJson(e.data())).toList() ??
+ [];
+
+ if (_list.isNotEmpty) {
+ return ListView.builder(
+ itemCount: _list.length, // Use the length of the list
+ padding: EdgeInsets.only(top: mq.height * .01),
+ physics: const BouncingScrollPhysics(),
+ itemBuilder: (context, index) {
+ //return Text('Name: ${list[index]}');
+ return ChatUserCard(user: _list[index]);
+ },
+ );
+ } else {
+ return const Center(
+ child: Text(
+ "No Connections Found...",
+ textAlign: TextAlign.center,
+ style: TextStyle(fontSize: 16),
+ ),
+ );
+ }
+ }
+ },
+ ),
+ ),
+ bottomNavigationBar: CustomBottomTabBar(
+ onTabSelected: _onTabSelected,
),
);
}
diff --git a/login/lib/screens/onboard_screen.dart b/login/lib/screens/onboard_screen.dart
index 3307030..3c6558a 100644
--- a/login/lib/screens/onboard_screen.dart
+++ b/login/lib/screens/onboard_screen.dart
@@ -2,6 +2,7 @@
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:login/auth/loginscreen.dart';
import 'package:login/auth/signuppage.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
@@ -94,7 +95,7 @@ class _OnBoardScreenState extends State {
),
// Buttons at the bottom
Padding(
- padding: const EdgeInsets.all(20.0),
+ padding: EdgeInsets.all(20.0.sp),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@@ -116,7 +117,7 @@ class _OnBoardScreenState extends State {
// Set button border
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
- 10.0), // Adjust the border radius as needed
+ 10.0.sp), // Adjust the border radius as needed
side: const BorderSide(
color: Colors.blue), // Set border color
),
@@ -149,29 +150,32 @@ class _OnBoardScreenState extends State {
child: const Text("Sign Up"),
),
if (_currentPage < 2)
- ElevatedButton(
- onPressed: () {
- _carouselController.jumpToPage(2);
- },
- style: ElevatedButton.styleFrom(
- // Set button size
- foregroundColor: Colors.grey,
- backgroundColor: Colors.white,
- minimumSize: const Size(120, 50),
- ),
- child: const Row(
- children: [
- Text(
- "Skip",
- style: TextStyle(color: Colors.blueAccent),
- ),
- SizedBox(width: 8.0), // Adjust the spacing as needed
- Icon(
- Icons.arrow_forward,
- color: Colors.blueAccent,
- size: 20.0, // Adjust the size as needed
- ),
- ],
+ Padding(
+ padding: EdgeInsets.all(16.0.sp),
+ child: InkWell(
+ onTap: () {
+ _carouselController.jumpToPage(2);
+ },
+ // style: ElevatedButton.styleFrom(
+ // // Set button size
+ // foregroundColor: Colors.grey,
+ // backgroundColor: Colors.white,
+ // minimumSize: const Size(120, 50),
+ // ),
+ child: const Row(
+ children: [
+ Text(
+ "Skip",
+ style: TextStyle(color: Colors.blueAccent),
+ ),
+ SizedBox(width: 8.0), // Adjust the spacing as needed
+ Icon(
+ Icons.arrow_forward,
+ color: Colors.blueAccent,
+ size: 20.0, // Adjust the size as needed
+ ),
+ ],
+ ),
),
),
if (_currentPage < 2)
diff --git a/login/lib/screens/profile_screen.dart b/login/lib/screens/profile_screen.dart
index 2cadd89..dc0098a 100644
--- a/login/lib/screens/profile_screen.dart
+++ b/login/lib/screens/profile_screen.dart
@@ -30,194 +30,191 @@ class _ProfileScreenState extends State {
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Scaffold(
- appBar: AppBar(
- title: const Text(
- StringConstants.profilescreen,
- textAlign: TextAlign.center,
+ appBar: AppBar(
+ title: const Text(
+ StringConstants.profilescreen,
+ textAlign: TextAlign.center,
+ ),
+ backgroundColor: Colors.lightBlue,
+ leading: InkWell(
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => const HomePage(),
+ ),
+ );
+ },
+ child: const Icon(
+ CupertinoIcons.chevron_back,
+ color: Colors.white,
),
- backgroundColor: Colors.lightBlue,
- leading: InkWell(
- onTap: () {
- Navigator.push(
- context,
- MaterialPageRoute(
- builder: (context) => const HomePage(),
- ),
- );
- },
- child: const Icon(
- CupertinoIcons.chevron_back,
- color: Colors.white,
- ),
+ ),
+ ),
+ floatingActionButton: Container(
+ height: 70,
+ width: 110,
+ padding: const EdgeInsets.only(bottom: 16.0, right: 16.0),
+ child: FloatingActionButton(
+ backgroundColor: Colors.red,
+ onPressed: () async {
+ Dialogs.showProgressBar(context);
+ await APIs.updateActiveStatus(false);
+ await APIs.auth.signOut().then((value) async {
+ Navigator.pop(context);
+ Navigator.pop(context);
+ Navigator.pushAndRemoveUntil(
+ context,
+ MaterialPageRoute(builder: (context) => const LoginPage()),
+ (route) => false);
+ });
+ },
+ child: const Row(
+ children: [
+ SizedBox(
+ width: 5,
+ ),
+ Text('LogOut'),
+ SizedBox(
+ width: 5,
+ ),
+ Icon(
+ Icons.exit_to_app,
+ color: Colors.white,
+ ),
+ ],
),
),
- floatingActionButton: Container(
- height: 70,
- width: 110,
- padding: const EdgeInsets.only(bottom: 16.0, right: 16.0),
- child: FloatingActionButton(
- backgroundColor: Colors.lightBlue,
- onPressed: () async {
- Dialogs.showProgressBar(context);
- await APIs.updateActiveStatus(false);
- await APIs.auth.signOut().then((value) async {
- Navigator.pop(context);
- Navigator.pop(context);
- Navigator.pushAndRemoveUntil(
- context,
- MaterialPageRoute(
- builder: (context) => const LoginPage()),
- (route) => false);
- });
- },
- child: const Row(
+ ),
+ body: Form(
+ key: _formKey,
+ child: SingleChildScrollView(
+ child: Padding(
+ padding: EdgeInsets.symmetric(
+ horizontal: mq.width * .05,
+ ),
+ child: Column(
children: [
SizedBox(
- width: 5,
- ),
- Text('LogOut'),
- SizedBox(
- width: 5,
- ),
- Icon(
- Icons.exit_to_app,
- color: Colors.white,
+ width: mq.width,
+ height: mq.height * .03,
),
- ],
- ),
- ),
- ),
- body: Form(
- key: _formKey,
- child: SingleChildScrollView(
- child: Padding(
- padding: EdgeInsets.symmetric(
- horizontal: mq.width * .05,
- ),
- child: Column(
- children: [
- SizedBox(
- width: mq.width,
- height: mq.height * .03,
- ),
- Stack(
- children: [
- //profile picture
- _image != null
- ?
-
- //local image
- ClipRRect(
- borderRadius:
- BorderRadius.circular(mq.height * .1),
- child: Image.file(File(_image!),
- width: mq.height * .2,
- height: mq.height * .2,
- fit: BoxFit.cover),
- )
- :
+ Stack(
+ children: [
+ //profile picture
+ _image != null
+ ?
- //image from server
- ClipRRect(
- borderRadius:
- BorderRadius.circular(mq.height * .1),
- child: CachedNetworkImage(
+ //local image
+ ClipRRect(
+ borderRadius:
+ BorderRadius.circular(mq.height * .1),
+ child: Image.file(File(_image!),
width: mq.height * .2,
height: mq.height * .2,
- fit: BoxFit.cover,
- imageUrl: widget.user.Image,
- errorWidget: (context, url, error) =>
- const CircleAvatar(
- child: Icon(CupertinoIcons.person)),
- ),
- ),
+ fit: BoxFit.cover),
+ )
+ :
- // edit image button
- Positioned(
- bottom: 0,
- right: 0,
- child: MaterialButton(
- elevation: 1,
- onPressed: () {
- _showBottomSheet();
- },
- color: Colors.white,
- shape: const CircleBorder(),
- child: const Icon(
- Icons.edit,
- color: Colors.blue,
+ //image from server
+ ClipRRect(
+ borderRadius:
+ BorderRadius.circular(mq.height * .1),
+ child: CachedNetworkImage(
+ width: mq.height * .2,
+ height: mq.height * .2,
+ fit: BoxFit.cover,
+ imageUrl: widget.user.Image,
+ errorWidget: (context, url, error) =>
+ const CircleAvatar(
+ child: Icon(CupertinoIcons.person)),
+ ),
),
+
+ // edit image button
+ Positioned(
+ bottom: 0,
+ right: 0,
+ child: MaterialButton(
+ elevation: 1,
+ onPressed: () {
+ _showBottomSheet();
+ },
+ color: Colors.white,
+ shape: const CircleBorder(),
+ child: const Icon(
+ Icons.edit,
+ color: Colors.blue,
),
- )
- ],
- ),
- SizedBox(
- width: mq.width,
- height: mq.height * .03,
- ),
- Text(
- widget.user.Email,
- style: const TextStyle(
- fontWeight: FontWeight.w200,
- fontSize: 16,
- ),
- ),
- TextFormField(
- initialValue: widget.user.Name,
- onSaved: (val) => APIs.me.Name = val ?? '',
- validator: (val) => val != null && val.isNotEmpty
- ? null
- : 'Required Field',
- decoration: InputDecoration(
- prefixIcon:
- const Icon(Icons.person, color: Colors.blue),
- border: OutlineInputBorder(
- borderRadius: BorderRadius.circular(12)),
- hintText: 'ex: Your Full Name',
- label: const Text('Name')),
- ),
- const SizedBox(
- height: 20,
- ),
- TextFormField(
- initialValue: widget.user.About,
- onSaved: (val) => APIs.me.About = val ?? '',
- validator: (val) => val != null && val.isNotEmpty
- ? null
- : 'Required Field',
- decoration: InputDecoration(
- prefixIcon: const Icon(Icons.info_outline,
- color: Colors.blue),
- border: OutlineInputBorder(
- borderRadius: BorderRadius.circular(12)),
- hintText: 'ex: About Yourself',
- label: const Text('About')),
- ),
- const SizedBox(
- height: 40,
- ),
- ElevatedButton.icon(
- style: ElevatedButton.styleFrom(
- shape: const StadiumBorder(),
- minimumSize: Size(mq.width * .5, mq.height * .06)),
- onPressed: () {
- if (_formKey.currentState!.validate()) {
- _formKey.currentState!.save();
- APIs.updateUserInfo().then((value) {
- Dialogs.showSnackbar(
- context, 'Profile Updated Successfully!');
- });
- }
- },
- icon: const Icon(Icons.edit, size: 28),
- label:
- const Text('UPDATE', style: TextStyle(fontSize: 16)),
+ ),
+ )
+ ],
+ ),
+ SizedBox(
+ width: mq.width,
+ height: mq.height * .03,
+ ),
+ Text(
+ widget.user.Email,
+ style: const TextStyle(
+ fontWeight: FontWeight.w200,
+ fontSize: 16,
),
- ],
- ),
+ ),
+ TextFormField(
+ initialValue: widget.user.Name,
+ onSaved: (val) => APIs.me.Name = val ?? '',
+ validator: (val) =>
+ val != null && val.isNotEmpty ? null : 'Required Field',
+ decoration: InputDecoration(
+ prefixIcon:
+ const Icon(Icons.person, color: Colors.blue),
+ border: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(12)),
+ hintText: 'ex: Your Full Name',
+ label: const Text('Name')),
+ ),
+ const SizedBox(
+ height: 20,
+ ),
+ TextFormField(
+ initialValue: widget.user.About,
+ onSaved: (val) => APIs.me.About = val ?? '',
+ validator: (val) =>
+ val != null && val.isNotEmpty ? null : 'Required Field',
+ decoration: InputDecoration(
+ prefixIcon:
+ const Icon(Icons.info_outline, color: Colors.blue),
+ border: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(12)),
+ hintText: 'ex: About Yourself',
+ label: const Text('About')),
+ ),
+ const SizedBox(
+ height: 40,
+ ),
+ ElevatedButton.icon(
+ style: ElevatedButton.styleFrom(
+ shape: const StadiumBorder(),
+ minimumSize: Size(mq.width * .5, mq.height * .06)),
+ onPressed: () {
+ if (_formKey.currentState!.validate()) {
+ _formKey.currentState!.save();
+ APIs.updateUserInfo().then((value) {
+ Dialogs.showSnackbar(
+ context, 'Profile Updated Successfully!');
+ });
+ }
+ },
+ icon: const Icon(Icons.edit, size: 28),
+ label: const Text('UPDATE', style: TextStyle(fontSize: 16)),
+ ),
+ ],
),
),
- )),
+ ),
+ ),
+ ),
);
}
@@ -282,7 +279,6 @@ class _ProfileScreenState extends State {
//take picture from camera button
ElevatedButton(
style: ElevatedButton.styleFrom(
- backgroundColor: Colors.white,
shape: const CircleBorder(),
fixedSize: Size(mq.width * .3, mq.height * .15)),
onPressed: () async {
diff --git a/login/lib/screens/settings_screen.dart b/login/lib/screens/settings_screen.dart
new file mode 100644
index 0000000..868ab02
--- /dev/null
+++ b/login/lib/screens/settings_screen.dart
@@ -0,0 +1,19 @@
+import 'package:flutter/material.dart';
+
+class SettingsScreen extends StatefulWidget {
+ const SettingsScreen({super.key});
+
+ @override
+ State createState() => _SettingsScreenState();
+}
+
+class _SettingsScreenState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: const Text("Settings"),
+ ),
+ );
+ }
+}
diff --git a/login/lib/screens/user_chat_screen.dart b/login/lib/screens/user_chat_screen.dart
index 3f80cd6..2a9e310 100644
--- a/login/lib/screens/user_chat_screen.dart
+++ b/login/lib/screens/user_chat_screen.dart
@@ -47,7 +47,7 @@ class _UserChatScreenState extends State {
}
//for storing all messages
- List _list = [];
+ List list = [];
//for handling message text controlling
final _textController = TextEditingController();
@override
@@ -57,10 +57,9 @@ class _UserChatScreenState extends State {
appBar: AppBar(
automaticallyImplyLeading: false,
flexibleSpace: _appBar(),
+ backgroundColor: const Color.fromRGBO(0, 163, 255, 1),
),
- backgroundColor: const Color.fromARGB(255, 234, 248, 255),
-
// AppBar(
// automaticallyImplyLeading: false,
// title: InkWell(
@@ -110,62 +109,75 @@ class _UserChatScreenState extends State {
// ),
// )),
// backgroundColor: const Color.fromARGB(255, 234, 248, 255),
- body: Column(
- children: [
- Expanded(
- child: StreamBuilder(
- stream: APIs.getAllMessages(widget.user),
- builder: (context, snapshot) {
- switch (snapshot.connectionState) {
- // if data s loading
- case ConnectionState.waiting:
- case ConnectionState.none:
- return const Center(
- child: CircularProgressIndicator(),
- );
+ body: Container(
+ decoration: const BoxDecoration(
+ //gradient: LinearGradient(colors: Colors.white ),
+ gradient: LinearGradient(
+ begin: Alignment.topLeft,
+ end: Alignment.bottomRight,
+ colors: [
+ Color.fromRGBO(0, 248, 248, 1),
+ Color.fromRGBO(0, 57, 89, 1),
+ ],
+ ),
+ ),
+ child: Column(
+ children: [
+ Expanded(
+ child: StreamBuilder(
+ stream: APIs.getAllMessages(widget.user),
+ builder: (context, snapshot) {
+ switch (snapshot.connectionState) {
+ // if data s loading
+ case ConnectionState.waiting:
+ case ConnectionState.none:
+ return const Center(
+ child: CircularProgressIndicator(),
+ );
- //if some or all data is loaded then show it
- case ConnectionState.active:
- case ConnectionState.done:
- final data = snapshot.data?.docs;
+ //if some or all data is loaded then show it
+ case ConnectionState.active:
+ case ConnectionState.done:
+ final data = snapshot.data?.docs;
- _newList = data
- ?.map((e) => Message.fromJson(e.data()))
- .toList() ??
- [];
+ _newList = data
+ ?.map((e) => Message.fromJson(e.data()))
+ .toList() ??
+ [];
- var _list = _newList.reversed.toList();
+ var list = _newList.reversed.toList();
- if (_list.isNotEmpty) {
- return ListView.builder(
- reverse: true,
- controller:
- _scrollController, // Assign the ScrollController
- itemCount: _list.length,
- padding: EdgeInsets.only(top: mq.height * .01),
- physics: const BouncingScrollPhysics(),
- itemBuilder: (context, index) {
- return MessageCard(
- message: _list[index],
- );
- },
- );
- } else {
- return Center(
- child: Text(
- "Say Hii 👋",
- textAlign: TextAlign.center,
- style: TextStyle(
- fontSize: 20.sp, fontWeight: FontWeight.w400),
- ),
- );
- }
- }
- },
+ if (list.isNotEmpty) {
+ return ListView.builder(
+ reverse: true,
+ controller:
+ _scrollController, // Assign the ScrollController
+ itemCount: list.length,
+ padding: EdgeInsets.only(top: mq.height * .01),
+ physics: const BouncingScrollPhysics(),
+ itemBuilder: (context, index) {
+ return MessageCard(
+ message: list[index],
+ );
+ },
+ );
+ } else {
+ return Center(
+ child: Text(
+ "Say Hii 👋",
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 20.sp, fontWeight: FontWeight.w400),
+ ),
+ );
+ }
+ }
+ },
+ ),
),
- ),
- _chatInput(),
- ],
+ _chatInput(),
+ ],
+ ),
),
),
);
diff --git a/login/lib/screens/view_profile_screen.dart b/login/lib/screens/view_profile_screen.dart
index 0e07cdd..4f6d621 100644
--- a/login/lib/screens/view_profile_screen.dart
+++ b/login/lib/screens/view_profile_screen.dart
@@ -1,6 +1,7 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:login/dialogs/my_date_util.dart';
import 'package:login/main.dart';
import 'package:login/model/chat_user_model.dart';
@@ -23,80 +24,134 @@ class _ViewProfileScreenState extends State {
onTap: () => FocusScope.of(context).unfocus(),
child: Scaffold(
//app bar
- appBar: AppBar(title: Text(widget.user.Name)),
- floatingActionButton: //user about
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
+ // appBar: AppBar(title: Text(widget.user.Name)),
+ // floatingActionButton: //user about
+ // Row(
+ // mainAxisAlignment: MainAxisAlignment.center,
+ // children: [
+ // const Text(
+ // 'Joined On: ',
+ // style: TextStyle(
+ // color: Colors.black87,
+ // fontWeight: FontWeight.w500,
+ // fontSize: 15),
+ // ),
+ // Text(
+ // MyDateUtil.getLastMessageTime(
+ // context: context,
+ // time: widget.user.CreatedAt,
+ // showYear: true),
+ // style: const TextStyle(color: Colors.black54, fontSize: 15)),
+ // ],
+ // ),
+
+ //body
+ body: Container(
+ decoration: const BoxDecoration(
+ //gradient: LinearGradient(colors: Colors.white ),
+ gradient: LinearGradient(
+ begin: Alignment.topLeft,
+ end: Alignment.bottomRight,
+ colors: [
+ Color.fromRGBO(0, 248, 248, 1),
+ Color.fromRGBO(0, 57, 89, 1),
+ ],
+ ),
+ ),
+ child: Padding(
+ padding: EdgeInsets.symmetric(horizontal: mq.width * .05),
+ child: Column(
children: [
- const Text(
- 'Joined On: ',
+ 50.verticalSpace,
+ Text(
+ widget.user.Name,
style: TextStyle(
- color: Colors.black87,
- fontWeight: FontWeight.w500,
- fontSize: 15),
+ fontSize: 20.sp,
+ fontWeight: FontWeight.w600,
+ color: Colors.white),
+ ),
+ // for adding some space
+ 20.verticalSpace,
+ //user profile picture
+ ClipRRect(
+ borderRadius: BorderRadius.circular(mq.height * .1),
+ child: CachedNetworkImage(
+ width: mq.height * .2,
+ height: mq.height * .2,
+ fit: BoxFit.cover,
+ imageUrl: widget.user.Image,
+ errorWidget: (context, url, error) =>
+ const CircleAvatar(child: Icon(CupertinoIcons.person)),
+ ),
),
- Text(
- MyDateUtil.getLastMessageTime(
- context: context,
- time: widget.user.CreatedAt,
- showYear: true),
- style: const TextStyle(color: Colors.black54, fontSize: 15)),
- ],
- ),
- //body
- body: Padding(
- padding: EdgeInsets.symmetric(horizontal: mq.width * .05),
- child: SingleChildScrollView(
- child: Column(
- children: [
- // for adding some space
- SizedBox(width: mq.width, height: mq.height * .03),
+ // user email label
- //user profile picture
- ClipRRect(
- borderRadius: BorderRadius.circular(mq.height * .1),
- child: CachedNetworkImage(
- width: mq.height * .2,
- height: mq.height * .2,
- fit: BoxFit.cover,
- imageUrl: widget.user.Image,
- errorWidget: (context, url, error) => const CircleAvatar(
- child: Icon(CupertinoIcons.person)),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(
+ 'Email: ',
+ style: TextStyle(
+ color: Colors.white,
+ fontWeight: FontWeight.w700,
+ fontSize: 16.sp,
),
),
-
- // for adding some space
- SizedBox(height: mq.height * .03),
-
- // user email label
Text(widget.user.Email,
- style:
- const TextStyle(color: Colors.black87, fontSize: 16)),
-
- // for adding some space
- SizedBox(height: mq.height * .02),
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 14.sp,
+ )),
+ ],
+ ),
+ 20.verticalSpace,
- //user about
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- const Text(
- 'About: ',
- style: TextStyle(
- color: Colors.black87,
- fontWeight: FontWeight.w500,
- fontSize: 15),
- ),
- Text(widget.user.About,
- style: const TextStyle(
- color: Colors.black54, fontSize: 15)),
- ],
+ //user about
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(
+ 'About: ',
+ style: TextStyle(
+ color: Colors.white,
+ fontWeight: FontWeight.w700,
+ fontSize: 18.sp,
+ ),
),
+ Text(widget.user.About,
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 18.sp,
+ )),
],
),
- ),
- )),
+ 20.verticalSpace,
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(
+ 'Joined On: ',
+ style: TextStyle(
+ color: Colors.white,
+ fontWeight: FontWeight.w700,
+ fontSize: 18.sp),
+ ),
+ Text(
+ MyDateUtil.getLastMessageTime(
+ context: context,
+ time: widget.user.CreatedAt,
+ showYear: true),
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 18.sp,
+ )),
+ ],
+ ),
+ ],
+ ),
+ ),
+ )),
);
}
}
diff --git a/login/lib/widgets/chat_user_card.dart b/login/lib/widgets/chat_user_card.dart
index 2524c96..224ac28 100644
--- a/login/lib/widgets/chat_user_card.dart
+++ b/login/lib/widgets/chat_user_card.dart
@@ -1,12 +1,12 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:login/dialogs/my_date_util.dart';
import 'package:login/dialogs/profile_dialog.dart';
import 'package:login/main.dart';
import 'package:login/model/chat_user_model.dart';
import 'package:login/model/messages.dart';
-import 'package:login/screens/profile_screen.dart';
import 'package:login/screens/user_chat_screen.dart';
import '../api/apis.dart';
@@ -29,7 +29,7 @@ class _ChatUserCardState extends State {
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.symmetric(horizontal: mq.width * .04, vertical: 4),
- // color: Colors.blue.shade100,
+ color: Colors.black,
elevation: 0.5,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
child: InkWell(
@@ -69,16 +69,27 @@ class _ChatUserCardState extends State {
),
//user name
- title: Text(widget.user.Name),
+ title: Text(
+ widget.user.Name,
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 16.sp,
+ fontWeight: FontWeight.w400),
+ ),
//last message
subtitle: Text(
- _message != null
- ? _message!.type == Type.image
- ? 'image'
- : _message!.msg
- : widget.user.About,
- maxLines: 1),
+ _message != null
+ ? _message!.type == Type.image
+ ? 'image'
+ : _message!.msg
+ : widget.user.About,
+ maxLines: 1,
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 16.sp,
+ fontWeight: FontWeight.w200),
+ ),
//last message time
trailing: _message == null
@@ -99,7 +110,7 @@ class _ChatUserCardState extends State {
Text(
MyDateUtil.getLastMessageTime(
context: context, time: _message!.sent),
- style: const TextStyle(color: Colors.black54),
+ style: const TextStyle(color: Colors.white),
),
);
},
diff --git a/login/lib/widgets/custom_bottom_navighationbar.dart b/login/lib/widgets/custom_bottom_navighationbar.dart
new file mode 100644
index 0000000..755657a
--- /dev/null
+++ b/login/lib/widgets/custom_bottom_navighationbar.dart
@@ -0,0 +1,87 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:login/screens/chat_screen.dart';
+import 'package:login/screens/homescreen.dart';
+import 'package:login/screens/settings_screen.dart';
+
+class CustomBottomTabBar extends StatefulWidget {
+ final Function(int) onTabSelected;
+
+ const CustomBottomTabBar({Key? key, required this.onTabSelected})
+ : super(key: key);
+
+ @override
+ _CustomBottomTabBarState createState() => _CustomBottomTabBarState();
+}
+
+class _CustomBottomTabBarState extends State {
+ int _selectedIndex = 0;
+
+ void _onItemTapped(int index) {
+ setState(() {
+ _selectedIndex = index;
+ });
+ if (index == 0) {
+ Navigator.push(
+ context,
+ MaterialPageRoute(builder: (context) => const HomePage()),
+ );
+ } else if (index == 1) {
+ Navigator.push(
+ context,
+ MaterialPageRoute(builder: (context) => const AIChatScreen()),
+ );
+ } else if (index == 2) {
+ Navigator.push(
+ context,
+ MaterialPageRoute(builder: (context) => const SettingsScreen()),
+ );
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Expanded(
+ child: Container(
+ decoration: const BoxDecoration(
+ gradient: LinearGradient(
+ begin: Alignment.topCenter,
+ end: Alignment.bottomCenter,
+ colors: [
+ Color.fromRGBO(0, 57, 89, 1),
+ Color.fromRGBO(0, 57, 89, 1),
+ ],
+ ),
+ ),
+ padding: EdgeInsets.only(left: 5.sp, right: 5.sp, bottom: 10.sp),
+ child: BottomNavigationBar(
+ items: const [
+ BottomNavigationBarItem(
+ icon: Icon(
+ Icons.chat,
+ ),
+ label: 'Chat',
+ ),
+ BottomNavigationBarItem(
+ icon: Icon(
+ Icons.chat,
+ ),
+ label: 'AI',
+ ),
+ BottomNavigationBarItem(
+ icon: Icon(
+ Icons.settings,
+ ),
+ label: 'Settings',
+ ),
+ ],
+ currentIndex: _selectedIndex,
+ selectedItemColor: Colors.white,
+ onTap: _onItemTapped,
+ backgroundColor: Colors.transparent,
+ unselectedItemColor: Colors.grey,
+ ),
+ ),
+ );
+ }
+}
diff --git a/login/pubspec.lock b/login/pubspec.lock
index 726d32f..3c44fa2 100644
--- a/login/pubspec.lock
+++ b/login/pubspec.lock
@@ -5,10 +5,10 @@ packages:
dependency: transitive
description:
name: _flutterfire_internals
- sha256: f5628cd9c92ed11083f425fd1f8f1bc60ecdda458c81d73b143aeda036c35fe7
+ sha256: "554f148e71e9e016d9c04d4af6b103ca3f74a1ceed7d7307b70a0f41e991eb77"
url: "https://pub.dev"
source: hosted
- version: "1.3.16"
+ version: "1.3.26"
args:
dependency: transitive
description:
@@ -125,10 +125,10 @@ packages:
dependency: transitive
description:
name: cross_file
- sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e
+ sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32"
url: "https://pub.dev"
source: hosted
- version: "0.3.3+8"
+ version: "0.3.4+1"
crypto:
dependency: transitive
description:
@@ -229,10 +229,10 @@ packages:
dependency: "direct main"
description:
name: firebase_core
- sha256: "96607c0e829a581c2a483c658f04e8b159964c3bae2730f73297070bc85d40bb"
+ sha256: "67bf0d5fd78f12f51c6b54a72f6141314136a1a90e98b1b7c45e7fac883254ed"
url: "https://pub.dev"
source: hosted
- version: "2.24.2"
+ version: "2.27.1"
firebase_core_platform_interface:
dependency: transitive
description:
@@ -245,10 +245,34 @@ packages:
dependency: transitive
description:
name: firebase_core_web
- sha256: d585bdf3c656c3f7821ba1bd44da5f13365d22fcecaf5eb75c4295246aaa83c0
+ sha256: "5377eaac3b9fe8aaf22638d87f92b62784f23572e132dfc029195e84d6cb37de"
url: "https://pub.dev"
source: hosted
- version: "2.10.0"
+ version: "2.12.0"
+ firebase_messaging:
+ dependency: "direct main"
+ description:
+ name: firebase_messaging
+ sha256: "34fac43b70d5c41dc864eeb52417128da1f68b0a48604a0c56cd3190f0f609b8"
+ url: "https://pub.dev"
+ source: hosted
+ version: "14.7.20"
+ firebase_messaging_platform_interface:
+ dependency: transitive
+ description:
+ name: firebase_messaging_platform_interface
+ sha256: "1dcf7d0d6776396bb2e488c53b0e4cc671c45a65717a73d881e52190d23aca3c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.5.28"
+ firebase_messaging_web:
+ dependency: transitive
+ description:
+ name: firebase_messaging_web
+ sha256: ceabccf24d15d03c89dfd6c7eaef11c58fbf00b9c76ebc94028408943b8d2bfd
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.7.0"
firebase_storage:
dependency: "direct main"
description:
@@ -340,10 +364,10 @@ packages:
dependency: transitive
description:
name: google_identity_services_web
- sha256: "0c56c2c5d60d6dfaf9725f5ad4699f04749fb196ee5a70487a46ef184837ccf6"
+ sha256: "9482364c9f8b7bd36902572ebc3a7c2b5c8ee57a9c93e6eb5099c1a9ec5265d8"
url: "https://pub.dev"
source: hosted
- version: "0.3.0+2"
+ version: "0.3.1+1"
google_sign_in:
dependency: "direct main"
description:
@@ -380,18 +404,18 @@ packages:
dependency: transitive
description:
name: google_sign_in_web
- sha256: "38e6ec2a7d65ec34bb7ae2db64a1d042b021330433b999e87330d45c688ff549"
+ sha256: fc0f14ed45ea616a6cfb4d1c7534c2221b7092cc4f29a709f0c3053cc3e821bd
url: "https://pub.dev"
source: hosted
- version: "0.12.3+1"
+ version: "0.12.4"
http:
dependency: "direct main"
description:
name: http
- sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba
+ sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
url: "https://pub.dev"
source: hosted
- version: "1.2.0"
+ version: "1.2.1"
http_parser:
dependency: transitive
description:
@@ -480,6 +504,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.6.7"
+ leak_tracker:
+ dependency: transitive
+ description:
+ name: leak_tracker
+ sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
+ url: "https://pub.dev"
+ source: hosted
+ version: "10.0.0"
+ leak_tracker_flutter_testing:
+ dependency: transitive
+ description:
+ name: leak_tracker_flutter_testing
+ sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
+ leak_tracker_testing:
+ dependency: transitive
+ description:
+ name: leak_tracker_testing
+ sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
lints:
dependency: transitive
description:
@@ -492,26 +540,26 @@ packages:
dependency: transitive
description:
name: matcher
- sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
+ sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
url: "https://pub.dev"
source: hosted
- version: "0.12.16"
+ version: "0.12.16+1"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
- sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
+ sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
url: "https://pub.dev"
source: hosted
- version: "0.5.0"
+ version: "0.8.0"
meta:
dependency: transitive
description:
name: meta
- sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
+ sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
url: "https://pub.dev"
source: hosted
- version: "1.10.0"
+ version: "1.11.0"
mime:
dependency: transitive
description:
@@ -532,10 +580,10 @@ packages:
dependency: transitive
description:
name: path
- sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
+ sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.dev"
source: hosted
- version: "1.8.3"
+ version: "1.9.0"
path_parsing:
dependency: transitive
description:
@@ -765,14 +813,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
+ vm_service:
+ dependency: transitive
+ description:
+ name: vm_service
+ sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
+ url: "https://pub.dev"
+ source: hosted
+ version: "13.0.0"
web:
dependency: transitive
description:
name: web
- sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
+ sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
url: "https://pub.dev"
source: hosted
- version: "0.3.0"
+ version: "0.5.1"
win32:
dependency: transitive
description:
@@ -798,5 +854,5 @@ packages:
source: hosted
version: "6.5.0"
sdks:
- dart: ">=3.2.3 <4.0.0"
- flutter: ">=3.16.0"
+ dart: ">=3.3.0 <4.0.0"
+ flutter: ">=3.19.0"
diff --git a/login/pubspec.yaml b/login/pubspec.yaml
index ee099bc..8865984 100644
--- a/login/pubspec.yaml
+++ b/login/pubspec.yaml
@@ -44,11 +44,13 @@ dependencies:
carousel_slider: ^4.2.1
flutter_svg: ^2.0.9
smooth_page_indicator: ^1.1.0
- http: ^1.2.0
+ http: ^1.2.1
chat_bubbles: ^1.5.0
image_picker: ^1.0.7
firebase_storage: ^11.6.0
flutter_screenutil: ^5.9.0
+ firebase_messaging: ^14.7.20
+
dev_dependencies:
flutter_test: