Added LikedUsersPage (first draft)

master
Rafael 2024-06-03 23:12:42 +02:00
parent 4bff849b13
commit e350bdf91c
2 changed files with 280 additions and 0 deletions

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../pages/conversations_page.dart'; import '../pages/conversations_page.dart';
import '../pages/home_page.dart'; import '../pages/home_page.dart';
import '../pages/liked_users_page.dart';
import '../pages/user_data_page.dart'; import '../pages/user_data_page.dart';
import '../pages/settings_page.dart'; import '../pages/settings_page.dart';
import '../pages/user_matching_page.dart'; import '../pages/user_matching_page.dart';
@ -76,6 +77,27 @@ class MyDrawer extends StatelessWidget {
), ),
), ),
// liked users tile
Padding(
padding: const EdgeInsets.only(left: 25),
child: ListTile(
title: const Text('Swiped Users List'),
leading: const Icon(Icons.format_list_bulleted),
onTap: () {
// pop the drawer
Navigator.pop(context);
// Navigate to HomePage?
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) =>
const LikedUsersPage(),
),
);
},
),
),
// chats list tile // chats list tile
Padding( Padding(
padding: const EdgeInsets.only(left: 25), padding: const EdgeInsets.only(left: 25),

View File

@ -0,0 +1,258 @@
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import '../constants.dart';
import '../services/auth/auth_service.dart';
import '../utils/helper.dart';
class LikedUsersPage extends StatefulWidget {
const LikedUsersPage({super.key});
@override
LikedUsersPageState createState() => LikedUsersPageState();
}
class LikedUsersPageState extends State<LikedUsersPage> {
final String currentUserId = AuthService().getCurrentUser()!.uid;
Future<List<DocumentSnapshot>> _fetchLikedUsers() async {
QuerySnapshot likedUsersSnapshot = await FirebaseFirestore.instance
.collection(Constants.dbCollectionUsers)
.doc(currentUserId)
.collection(Constants.dbCollectionSwipes)
.where('liked', isEqualTo: true)
.get();
List<String> likedUserIds =
likedUsersSnapshot.docs.map((doc) => doc.id).toList();
List<DocumentSnapshot> likedUsers = [];
for (String userId in likedUserIds) {
DocumentSnapshot userDoc = await FirebaseFirestore.instance
.collection(Constants.dbCollectionUsers)
.doc(userId)
.get();
likedUsers.add(userDoc);
}
return likedUsers;
}
Future<bool> _hasMatch(String userId) async {
DocumentSnapshot matchDoc = await FirebaseFirestore.instance
.collection(Constants.dbCollectionUsers)
.doc(currentUserId)
.collection(Constants.dbCollectionMatches)
.doc(userId)
.get();
return matchDoc.exists;
}
Future<void> _unlikeUser(String userId) async {
try {
await FirebaseFirestore.instance
.collection(Constants.dbCollectionUsers)
.doc(currentUserId)
.collection(Constants.dbCollectionSwipes)
.doc(userId)
.delete(); //.update({'liked': false});
setState(() {}); // Refresh the UI
} catch (e) {
showMsg(context, 'Error unlike', e.toString());
}
}
void _showMatchMessage() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Match Exists'),
content: const Text(
'You cannot unlike a user with whom you have a match.',
),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('Close'),
),
],
);
},
);
}
Future<void> _showConfirmationDialog(String userId, String userName) async {
bool? confirm = await showDialog<bool>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Confirm Unlike'),
content: Text('Are you sure you want to unlike $userName?'),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(false),
child: const Text('Cancel'),
),
TextButton(
onPressed: () => Navigator.of(context).pop(true),
child: const Text('Confirm'),
),
],
);
},
);
if (confirm == true) {
await _unlikeUser(userId);
}
}
void _showUserInfo(DocumentSnapshot user) {
Map<String, dynamic> userMap = user.data() as Map<String, dynamic>;
bool hasName = userMap.containsKey(Constants.dbFieldUsersName);
bool hasBio = userMap.containsKey(Constants.dbFieldUsersBio);
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: hasName
? Text(user[Constants.dbFieldUsersName])
: const Text('Name: n/a'),
content: hasBio
? Text(user[Constants.dbFieldUsersBio])
: const Text('Bio: n/a'),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('Close'),
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Liked Users'),
),
body: FutureBuilder<List<DocumentSnapshot>>(
future: _fetchLikedUsers(),
builder: (BuildContext context,
AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
return const Center(child: Text('No liked users found.'));
} else {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (BuildContext context, int index) {
DocumentSnapshot user = snapshot.data![index];
return FutureBuilder<bool>(
future: _hasMatch(user.id),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
bool hasMatch = snapshot.data ?? false;
return UserInfoTile(
user: user,
hasMatch: hasMatch,
onUnlike: () {
Map<String, dynamic> userMap =
user.data() as Map<String, dynamic>;
bool hasName =
userMap.containsKey(Constants.dbFieldUsersName);
_showConfirmationDialog(
user.id,
(hasName
? user[Constants.dbFieldUsersName]
: 'Name: n/a'),
);
}, //_unlikeUser(user.id),
onShowMatchMessage: _showMatchMessage,
onViewInfo: () => _showUserInfo(user),
);
},
);
},
);
}
},
),
);
}
}
class UserInfoTile extends StatelessWidget {
final DocumentSnapshot user;
final bool hasMatch;
final VoidCallback onUnlike;
final VoidCallback onShowMatchMessage;
final VoidCallback onViewInfo;
const UserInfoTile({
super.key,
required this.user,
required this.hasMatch,
required this.onUnlike,
required this.onShowMatchMessage,
required this.onViewInfo,
});
@override
Widget build(BuildContext context) {
Map<String, dynamic> userMap = user.data() as Map<String, dynamic>;
bool hasPictureUrl = userMap.containsKey(Constants.dbFieldUsersProfilePic);
bool hasName = userMap.containsKey(Constants.dbFieldUsersName);
bool hasBio = userMap.containsKey(Constants.dbFieldUsersBio);
return Card(
margin: const EdgeInsets.all(8.0),
child: ListTile(
leading: hasPictureUrl == true &&
user[Constants.dbFieldUsersProfilePic] != null
? CircleAvatar(
backgroundImage:
NetworkImage(user[Constants.dbFieldUsersProfilePic]),
)
: const CircleAvatar(child: Icon(Icons.person)),
title: hasName
? Text(
'${user[Constants.dbFieldUsersName]} ${user[Constants.dbFieldUsersName]} ${user[Constants.dbFieldUsersName]}',
overflow: TextOverflow.ellipsis,
maxLines: 1,
)
: null,
subtitle: hasBio
? Text(
user[Constants.dbFieldUsersBio],
overflow: TextOverflow.ellipsis,
maxLines: 3,
)
: null,
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: const Icon(Icons.contact_page_outlined),
onPressed: onViewInfo,
),
IconButton(
icon: Icon(hasMatch ? Icons.lock_outline : Icons.delete_outline),
onPressed: hasMatch ? onShowMatchMessage : onUnlike,
),
],
),
),
);
}
}