From 3bc929b0ecf782ed6ebff126ac9591447ba67684 Mon Sep 17 00:00:00 2001 From: Alireza Mohammadian Date: Mon, 1 Apr 2024 13:11:42 -0700 Subject: [PATCH] follow --- lib/data/firebase_service/firestor.dart | 41 ++++++- lib/screen/explore.dart | 155 +++++++++++++++++------- lib/screen/profile_screen.dart | 123 ++++++++++++++++--- lib/widgets/navigation.dart | 8 +- lib/widgets/reels_item.dart | 2 +- 5 files changed, 264 insertions(+), 65 deletions(-) diff --git a/lib/data/firebase_service/firestor.dart b/lib/data/firebase_service/firestor.dart index 06d63ab..ef160f7 100644 --- a/lib/data/firebase_service/firestor.dart +++ b/lib/data/firebase_service/firestor.dart @@ -1,3 +1,5 @@ +import 'dart:ffi'; + import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter_instagram_clone/data/model/usermodel.dart'; @@ -28,11 +30,11 @@ class Firebase_Firestor { return true; } - Future getUser() async { + Future getUser({String? UID}) async { try { final user = await _firebaseFirestore .collection('users') - .doc(_auth.currentUser!.uid) + .doc(UID != null ? UID : _auth.currentUser!.uid) .get(); final snapuser = user.data()!; return Usermodel( @@ -133,4 +135,39 @@ class Firebase_Firestor { } return res; } + + Future flollow({ + required String uid, + }) async { + DocumentSnapshot snap = await _firebaseFirestore + .collection('users') + .doc(_auth.currentUser!.uid) + .get(); + List following = (snap.data()! as dynamic)['following']; + try { + if (following.contains(uid)) { + _firebaseFirestore + .collection('users') + .doc(_auth.currentUser!.uid) + .update({ + 'following': FieldValue.arrayRemove([uid]) + }); + await _firebaseFirestore.collection('users').doc(uid).update({ + 'followers': FieldValue.arrayRemove([_auth.currentUser!.uid]) + }); + } else { + _firebaseFirestore + .collection('users') + .doc(_auth.currentUser!.uid) + .update({ + 'following': FieldValue.arrayUnion([uid]) + }); + _firebaseFirestore.collection('users').doc(uid).update({ + 'followers': FieldValue.arrayUnion([_auth.currentUser!.uid]) + }); + } + } on Exception catch (e) { + print(e.toString()); + } + } } diff --git a/lib/screen/explore.dart b/lib/screen/explore.dart index 27eb0ef..ae0ffa3 100644 --- a/lib/screen/explore.dart +++ b/lib/screen/explore.dart @@ -1,6 +1,8 @@ import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:date_format/date_format.dart'; import 'package:flutter/material.dart'; import 'package:flutter_instagram_clone/screen/post_screen.dart'; +import 'package:flutter_instagram_clone/screen/profile_screen.dart'; import 'package:flutter_instagram_clone/util/image_cached.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; @@ -15,6 +17,7 @@ class ExploreScreen extends StatefulWidget { class _ExploreScreenState extends State { final search = TextEditingController(); final FirebaseFirestore _firebaseFirestore = FirebaseFirestore.instance; + bool show = true; @override Widget build(BuildContext context) { return Scaffold( @@ -24,57 +27,108 @@ class _ExploreScreenState extends State { child: CustomScrollView( slivers: [ SearchBox(), - StreamBuilder( - stream: _firebaseFirestore.collection('posts').snapshots(), - builder: (context, snapshot) { - if (!snapshot.hasData) { - return const SliverToBoxAdapter( - child: Center( - child: CircularProgressIndicator(), + if (show) + StreamBuilder( + stream: _firebaseFirestore.collection('posts').snapshots(), + builder: (context, snapshot) { + if (!snapshot.hasData) { + return const SliverToBoxAdapter( + child: Center( + child: CircularProgressIndicator(), + ), + ); + } + return SliverGrid( + delegate: SliverChildBuilderDelegate( + (context, index) { + final snap = snapshot.data!.docs[index]; + return GestureDetector( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => PostScreen( + snap.data(), + ), + ), + ); + }, + child: Container( + decoration: BoxDecoration( + color: Colors.grey, + ), + child: CachedImage( + snap['postImage'], + ), + ), + ); + }, + childCount: snapshot.data!.docs.length, + ), + gridDelegate: SliverQuiltedGridDelegate( + crossAxisCount: 3, + mainAxisSpacing: 3, + crossAxisSpacing: 3, + pattern: const [ + QuiltedGridTile(2, 1), + QuiltedGridTile(2, 2), + QuiltedGridTile(1, 1), + QuiltedGridTile(1, 1), + QuiltedGridTile(1, 1), + ], ), ); - } - return SliverGrid( - delegate: SliverChildBuilderDelegate( - (context, index) { - final snap = snapshot.data!.docs[index]; - return GestureDetector( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => PostScreen( - snap.data(), + }, + ), + if (!show) + StreamBuilder( + stream: _firebaseFirestore + .collection('users') + .where('username', isGreaterThanOrEqualTo: search.text) + .snapshots(), + builder: (context, snapshot) { + if (!snapshot.hasData) { + return const SliverToBoxAdapter( + child: Center(child: CircularProgressIndicator())); + } + return SliverPadding( + padding: + EdgeInsets.symmetric(horizontal: 15.w, vertical: 5.h), + sliver: SliverList( + delegate: SliverChildBuilderDelegate( + (context, index) { + final snap = snapshot.data!.docs[index]; + return Column( + children: [ + SizedBox(height: 10.h), + GestureDetector( + onTap: () { + Navigator.of(context).push(MaterialPageRoute( + builder: (context) => + ProfileScreen(Uid: snap.id), + )); + }, + child: Row( + children: [ + CircleAvatar( + radius: 23.r, + backgroundImage: NetworkImage( + snap['profile'], + ), + ), + SizedBox(width: 15.w), + Text(snap['username']), + ], + ), ), - ), + ], ); }, - child: Container( - decoration: BoxDecoration( - color: Colors.grey, - ), - child: CachedImage( - snap['postImage'], - ), - ), - ); - }, - childCount: snapshot.data!.docs.length, - ), - gridDelegate: SliverQuiltedGridDelegate( - crossAxisCount: 3, - mainAxisSpacing: 3, - crossAxisSpacing: 3, - pattern: const [ - QuiltedGridTile(2, 1), - QuiltedGridTile(2, 2), - QuiltedGridTile(1, 1), - QuiltedGridTile(1, 1), - QuiltedGridTile(1, 1), - ], - ), - ); - }, - ), + childCount: snapshot.data!.docs.length, + ), + ), + ); + }, + ) ], ), ), @@ -105,6 +159,15 @@ class _ExploreScreenState extends State { SizedBox(width: 10.w), Expanded( child: TextField( + onChanged: (value) { + setState(() { + if (value.length > 0) { + show = false; + } else { + show = true; + } + }); + }, controller: search, decoration: const InputDecoration( hintText: 'Search User', diff --git a/lib/screen/profile_screen.dart b/lib/screen/profile_screen.dart index a3cbe41..bc8fddc 100644 --- a/lib/screen/profile_screen.dart +++ b/lib/screen/profile_screen.dart @@ -10,7 +10,8 @@ import 'package:flutter_instagram_clone/widgets/post_widget.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; class ProfileScreen extends StatefulWidget { - const ProfileScreen({super.key}); + String Uid; + ProfileScreen({super.key, required this.Uid}); @override State createState() => _ProfileScreenState(); @@ -20,6 +21,34 @@ class _ProfileScreenState extends State { final FirebaseFirestore _firebaseFirestore = FirebaseFirestore.instance; final FirebaseAuth _auth = FirebaseAuth.instance; int post_lenght = 0; + bool yourse = false; + List following = []; + bool follow = false; + @override + void initState() { + // TODO: implement initState + super.initState(); + getdata(); + if (widget.Uid == _auth.currentUser!.uid) { + setState(() { + yourse = true; + }); + } + } + + getdata() async { + DocumentSnapshot snap = await _firebaseFirestore + .collection('users') + .doc(_auth.currentUser!.uid) + .get(); + following = (snap.data()! as dynamic)['following']; + if (following.contains(widget.Uid)) { + setState(() { + follow = true; + }); + } + } + @override Widget build(BuildContext context) { return DefaultTabController( @@ -31,7 +60,7 @@ class _ProfileScreenState extends State { slivers: [ SliverToBoxAdapter( child: FutureBuilder( - future: Firebase_Firestor().getUser(), + future: Firebase_Firestor().getUser(UID: widget.Uid), builder: (context, snapshot) { if (!snapshot.hasData) { return const Center(child: CircularProgressIndicator()); @@ -43,7 +72,7 @@ class _ProfileScreenState extends State { StreamBuilder( stream: _firebaseFirestore .collection('posts') - .where('uid', isEqualTo: _auth.currentUser!.uid) + .where('uid', isEqualTo: widget.Uid) .snapshots(), builder: (context, snapshot) { if (!snapshot.hasData) { @@ -184,18 +213,84 @@ class _ProfileScreenState extends State { ), ), SizedBox(height: 20.h), - Padding( - padding: EdgeInsets.symmetric(horizontal: 13.w), - child: Container( - alignment: Alignment.center, - height: 30.h, - width: double.infinity, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5.r), - border: Border.all(color: Colors.grey.shade400), + Visibility( + visible: !follow, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 13.w), + child: GestureDetector( + onTap: () { + if (yourse == false) { + Firebase_Firestor().flollow(uid: widget.Uid); + setState(() { + follow = true; + }); + } + }, + child: Container( + alignment: Alignment.center, + height: 30.h, + width: double.infinity, + decoration: BoxDecoration( + color: yourse ? Colors.white : Colors.blue, + borderRadius: BorderRadius.circular(5.r), + border: Border.all( + color: yourse ? Colors.grey.shade400 : Colors.blue), + ), + child: yourse + ? Text('Edit Your Profile') + : Text( + 'Follow', + style: TextStyle(color: Colors.white), + ), + ), + ), + ), + ), + Visibility( + visible: follow, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 13.w), + child: Row( + children: [ + Expanded( + child: GestureDetector( + onTap: () { + Firebase_Firestor().flollow(uid: widget.Uid); + setState(() { + follow = false; + }); + }, + child: Container( + alignment: Alignment.center, + height: 30.h, + width: 100.w, + decoration: BoxDecoration( + color: Colors.grey.shade200, + borderRadius: BorderRadius.circular(5.r), + border: Border.all(color: Colors.grey.shade200), + ), + child: Text('Unfollow')), + ), + ), + SizedBox(width: 8.w), + Expanded( + child: Container( + alignment: Alignment.center, + height: 30.h, + width: 100.w, + decoration: BoxDecoration( + color: Colors.grey.shade200, + borderRadius: BorderRadius.circular(5.r), + border: Border.all(color: Colors.grey.shade200), + ), + child: Text( + 'Message', + style: TextStyle(color: Colors.black), + ), + ), + ), + ], ), - child: Text('Edit Your Profile'), ), ), SizedBox(height: 5.h), diff --git a/lib/widgets/navigation.dart b/lib/widgets/navigation.dart index 7bdd1f4..c1ba1bf 100644 --- a/lib/widgets/navigation.dart +++ b/lib/widgets/navigation.dart @@ -1,3 +1,4 @@ +import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_instagram_clone/screen/add_screen.dart'; @@ -19,6 +20,7 @@ int _currentIndex = 0; class _Navigations_ScreenState extends State { late PageController pageController; + final FirebaseAuth _auth = FirebaseAuth.instance; @override void initState() { // TODO: implement initState @@ -83,12 +85,14 @@ class _Navigations_ScreenState extends State { body: PageView( controller: pageController, onPageChanged: onPageChanged, - children: const [ + children: [ HomeScreen(), ExploreScreen(), AddScreen(), ReelScreen(), - ProfileScreen(), + ProfileScreen( + Uid: _auth.currentUser!.uid, + ), ], ), ); diff --git a/lib/widgets/reels_item.dart b/lib/widgets/reels_item.dart index 32af7c0..7e1a57c 100644 --- a/lib/widgets/reels_item.dart +++ b/lib/widgets/reels_item.dart @@ -159,7 +159,7 @@ class _ReelsItemState extends State { initialChildSize: 0.6, minChildSize: 0.2, builder: (context, scrollController) { - return Comment(widget.snapshot['postId'], 'reels'); + return Comment('reels', widget.snapshot['postId']); }, ), );