From 5e61b132b8d3170d224cf0eb3cfafe27c36c584d Mon Sep 17 00:00:00 2001 From: chamod udara Date: Tue, 6 Aug 2024 01:55:15 +0530 Subject: [PATCH] add follow user method --- lib/pages/edit_profile.dart | 16 +++++ lib/pages/profilepage.dart | 106 ++++++++++++++++++++++---------- lib/pages/serchpage.dart | 74 +++++++++++----------- lib/pages/sing_up_page.dart | 44 ++++++------- lib/provider/user_provider.dart | 12 +++- lib/service/firestore.dart | 49 +++++++++++++++ 6 files changed, 209 insertions(+), 92 deletions(-) create mode 100644 lib/pages/edit_profile.dart diff --git a/lib/pages/edit_profile.dart b/lib/pages/edit_profile.dart new file mode 100644 index 0000000..0a8fae6 --- /dev/null +++ b/lib/pages/edit_profile.dart @@ -0,0 +1,16 @@ +import 'package:flutter/material.dart'; +import 'package:instagram_clone/util/colors.dart'; + +class EditProfilePage extends StatelessWidget { + const EditProfilePage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: mobileSearchColor, + appBar: AppBar( + automaticallyImplyLeading: true, + ), + ); + } +} diff --git a/lib/pages/profilepage.dart b/lib/pages/profilepage.dart index 1eab726..02f8688 100644 --- a/lib/pages/profilepage.dart +++ b/lib/pages/profilepage.dart @@ -1,9 +1,12 @@ import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:instagram_clone/models/user_model.dart'; +import 'package:instagram_clone/pages/edit_profile.dart'; import 'package:instagram_clone/provider/user_provider.dart'; import 'package:instagram_clone/service/authentication.dart'; +import 'package:instagram_clone/service/firestore.dart'; import 'package:instagram_clone/util/colors.dart'; import 'package:instagram_clone/util/text_styles.dart'; import 'package:provider/provider.dart'; @@ -21,9 +24,10 @@ class _ProfilePageState extends State { var userDetails = {}; var postDetails; int postCount = 0; - int followCount = 0; + int followersCount = 0; int followingCount = 0; bool isLoading = false; + bool isfollowing = false; @override void initState() { getUserData(); @@ -48,7 +52,15 @@ class _ProfilePageState extends State { postDetails = postSnap; postCount = postSnap.docs.length; followingCount = userSnap.data()!["following"].length; - followCount = userSnap.data()!["followers"].length; + followersCount = userSnap.data()!["followers"].length; + //check user currently follow or not + String uid = FirebaseAuth.instance.currentUser!.uid; + DocumentSnapshot snapshot = + await FirebaseFirestore.instance.collection("users").doc(uid).get(); + List followings = (snapshot.data() as dynamic)["following"]; + if (followings.contains(widget.userId)) { + isfollowing = true; + } setState(() {}); } catch (err) { print(err.toString()); @@ -58,6 +70,21 @@ class _ProfilePageState extends State { }); } + //follow user + void followNewUser() async { + await FireStoreMethods().followUser( + FirebaseAuth.instance.currentUser!.uid, widget.userId, context); + } + + //void edit profile + void editProfile() { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const EditProfilePage(), + )); + } + @override Widget build(BuildContext context) { UserModel currentUser = Provider.of(context).getCurrentUser; @@ -137,23 +164,29 @@ class _ProfilePageState extends State { ), const Padding(padding: EdgeInsets.only(bottom: 8)), //edit/follow button - GestureDetector( - onTap: () {}, - child: Container( - width: MediaQuery.of(context).size.width * 0.55, - padding: const EdgeInsets.symmetric(vertical: 7), - decoration: - const BoxDecoration(color: ternerycolor), - child: Center( - child: Text( - userDetails["uid"] == currentUser.user - ? "Edit Profile" - : "Follow", - style: title, - ), - ), - ), - ) + userDetails["uid"] == currentUser.user + ? GestureDetector( + onTap: editProfile, + child: reusableButton("Edit Profile")) + : isfollowing + ? GestureDetector( + onTap: () { + followNewUser(); + setState(() { + isfollowing = false; + followersCount--; + }); + }, + child: reusableButton("UnFollow")) + : GestureDetector( + onTap: () { + followNewUser(); + setState(() { + isfollowing = true; + followersCount++; + }); + }, + child: reusableButton("Follow")), ], ) ], @@ -166,8 +199,8 @@ class _ProfilePageState extends State { mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ statusCol("posts", postCount), - statusCol("following", followCount), - statusCol("followers", followingCount), + statusCol("following", followingCount), + statusCol("followers", followersCount), ], ), const SizedBox( @@ -182,20 +215,14 @@ class _ProfilePageState extends State { builder: (context, snapshot) { return MasonryGridView.count( crossAxisCount: 3, - itemCount: (snapshot.data! as dynamic).docs.length, - crossAxisSpacing: 0, - mainAxisSpacing: 0, + itemCount: (snapshot.data as dynamic).docs.length, + crossAxisSpacing: 2, + mainAxisSpacing: 2, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) { - return Container( - padding: const EdgeInsets.only( - top: 3, left: 3, right: 3), - color: mobileBackgroundColor, - child: Image.network( - (snapshot.data! as dynamic).docs[index] - ["posturl"], - ), + return Image.network( + (snapshot.data as dynamic).docs[index]["posturl"], ); }, ); @@ -223,4 +250,19 @@ class _ProfilePageState extends State { ], ); } + + //reusable button + Widget reusableButton(String text) { + return Container( + width: MediaQuery.of(context).size.width * 0.55, + padding: const EdgeInsets.symmetric(vertical: 7), + decoration: const BoxDecoration(color: ternerycolor), + child: Center( + child: Text( + text, + style: title, + ), + ), + ); + } } diff --git a/lib/pages/serchpage.dart b/lib/pages/serchpage.dart index 5821e1b..9b3a7d8 100644 --- a/lib/pages/serchpage.dart +++ b/lib/pages/serchpage.dart @@ -88,44 +88,46 @@ class _SerchPageState extends State { }, ) //get all posts - : StreamBuilder( - stream: FirebaseFirestore.instance - .collection("posts") - .orderBy("date") - .snapshots(), - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return const Center( - child: CircularProgressIndicator(), - ); - } - if (!snapshot.hasData) { - return Center( - child: Text( - "No Post Yet.", - style: hinttext, - ), - ); - } - //show all posts - return MasonryGridView.count( - crossAxisCount: 3, - itemCount: (snapshot.data! as dynamic).docs.length, - crossAxisSpacing: 0, - mainAxisSpacing: 0, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - return Container( - padding: const EdgeInsets.only(top: 3, left: 3, right: 3), - color: mobileBackgroundColor, - child: Image.network( - (snapshot.data! as dynamic).docs[index]["posturl"], + : Padding( + padding: const EdgeInsets.only(top: 10), + child: StreamBuilder( + stream: FirebaseFirestore.instance + .collection("posts") + .orderBy("date") + .snapshots(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center( + child: CircularProgressIndicator(), + ); + } + if (!snapshot.hasData) { + return Center( + child: Text( + "No Post Yet.", + style: hinttext, ), ); - }, - ); - }, + } + //show all posts + return SingleChildScrollView( + child: MasonryGridView.count( + scrollDirection: Axis.vertical, + crossAxisCount: 3, + itemCount: (snapshot.data! as dynamic).docs.length, + crossAxisSpacing: 2, + mainAxisSpacing: 2, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + return Image.network( + (snapshot.data! as dynamic).docs[index]["posturl"], + ); + }, + ), + ); + }, + ), ), ); } diff --git a/lib/pages/sing_up_page.dart b/lib/pages/sing_up_page.dart index 08aacdd..4656551 100644 --- a/lib/pages/sing_up_page.dart +++ b/lib/pages/sing_up_page.dart @@ -52,16 +52,16 @@ class _SingUpPageState extends State { //checking - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - backgroundColor: textboxfillcolor, - content: Text( - "waiting", - style: body, - ), - ), - ); - print("waiting"); + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // backgroundColor: textboxfillcolor, + // content: Text( + // "waiting", + // style: body, + // ), + // ), + // ); + // print("waiting"); // await _authServises.singUpUser( email: _emailController.text, @@ -71,18 +71,18 @@ class _SingUpPageState extends State { proPic: _image, context: context); //checking - ScaffoldMessenger.of(context).showSnackBar( - //checking - SnackBar( - backgroundColor: textboxfillcolor, - content: Text( - "done", - style: body, - ), - ), - ); - print("done"); - // + // ScaffoldMessenger.of(context).showSnackBar( + // //checking + // SnackBar( + // backgroundColor: textboxfillcolor, + // content: Text( + // "done", + // style: body, + // ), + // ), + // ); + // print("done"); + // // setState(() { isLoading = !isLoading; }); diff --git a/lib/provider/user_provider.dart b/lib/provider/user_provider.dart index c70372e..cbed2a0 100644 --- a/lib/provider/user_provider.dart +++ b/lib/provider/user_provider.dart @@ -3,9 +3,17 @@ import 'package:instagram_clone/models/user_model.dart'; import 'package:instagram_clone/service/authentication.dart'; class UserProvider extends ChangeNotifier { - UserModel? _currentUser; + UserModel _currentUser = UserModel( + user: "", + username: "", + email: "", + password: "", + bio: "", + proPic: "", + followres: [], + following: []); final Authentication _auth = Authentication(); - UserModel get getCurrentUser => _currentUser!; + UserModel get getCurrentUser => _currentUser; // UserProvider() { // refreshUser(); diff --git a/lib/service/firestore.dart b/lib/service/firestore.dart index 7167128..a138a09 100644 --- a/lib/service/firestore.dart +++ b/lib/service/firestore.dart @@ -114,4 +114,53 @@ class FireStoreMethods { print(err.toString()); } } + + //follow or unfollow user + Future followUser( + String userId, String foreignId, BuildContext context) async { + try { + //get current user doc + DocumentSnapshot snapshot = await FirebaseFirestore.instance + .collection("users") + .doc(userId) + .get(); + //get current user following list + List followings = (snapshot.data() as dynamic)["following"]; + if (followings.contains(foreignId)) { + //unfollow from current user + await FirebaseFirestore.instance + .collection("users") + .doc(userId) + .update({ + "following": FieldValue.arrayRemove([foreignId]) + }); + //unfollow from forieng user + await FirebaseFirestore.instance + .collection("users") + .doc(foreignId) + .update({ + "followers": FieldValue.arrayRemove([userId]) + }); + } else { + //follow foreign user + await FirebaseFirestore.instance + .collection("users") + .doc(userId) + .update({ + "following": FieldValue.arrayUnion([foreignId]) + }); + //update foreign user followers list + await FirebaseFirestore.instance + .collection("users") + .doc(foreignId) + .update({ + "followers": FieldValue.arrayUnion([userId]) + }); + } + } catch (err) { + if (context.mounted) { + massage(err.toString(), context); + } + } + } }