Skip to content

Commit

Permalink
ref: use User objects everywhere instead of both User and OtherUser
Browse files Browse the repository at this point in the history
  • Loading branch information
oltimaloku committed Jun 1, 2024
1 parent aaac287 commit 4f1fc05
Show file tree
Hide file tree
Showing 12 changed files with 89 additions and 58 deletions.
1 change: 1 addition & 0 deletions client/assets/map/style.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
"elementType": "labels.text.fill",
"stylers": [
{

"color": "#98a5be"
}
]
Expand Down
27 changes: 13 additions & 14 deletions client/lib/features/friends/services/user_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@ import 'dart:developer';

import 'package:georeal/constants/env_variables.dart';
import 'package:georeal/models/friend_request.dart';
import 'package:georeal/models/other_user.dart';
import 'package:georeal/models/user.dart';
import 'package:http/http.dart' as http;

class UserService {
static Future<List<OtherUser>> getAllUsers() async {
static Future<List<User>> getAllUsers() async {
try {
final response = await http.get(Uri.parse('${EnvVariables.uri}/users'));

if (response.statusCode == 200) {
final List<dynamic> usersJson = json.decode(response.body);
log(usersJson.toString());
List<OtherUser> users =
usersJson.map((user) => OtherUser.fromMap(user)).toList();
log(usersJson.toString(), name: 'getAllUsers');
for (var user in usersJson) {
log(user.toString(), name: 'getAllUsers');
}
List<User> users = usersJson.map((user) => User.fromMap(user)).toList();

return users;
} else {
Expand All @@ -28,10 +30,8 @@ class UserService {
}
}

static Future<OtherUser> getUserByUsername(
String username, int userId) async {
static Future<User> getUserByUsername(String username, int userId) async {
try {
log('Fetching user with username: $username');
final response = await http.get(
Uri.parse(
'${EnvVariables.uri}/user?username=${Uri.encodeComponent(username)}&user_id=${Uri.encodeComponent(userId.toString())}'),
Expand All @@ -40,7 +40,7 @@ class UserService {

if (response.statusCode == 200) {
final userJson = json.decode(response.body);
return OtherUser.fromMap(userJson);
return User.fromMap(userJson);
} else {
throw Exception(
'Failed to load user with status code: ${response.statusCode}');
Expand All @@ -53,7 +53,6 @@ class UserService {

static Future<String> sendFriendRequest(int senderId, int receiverId) async {
try {
log('Sending friend request from $senderId to $receiverId');
http.Response response = await http.post(
Uri.parse(
'${EnvVariables.uri}/users/friend_request?sender_id=${Uri.encodeComponent(senderId.toString())}&receiver_id=${Uri.encodeComponent(receiverId.toString())}'),
Expand Down Expand Up @@ -134,16 +133,16 @@ class UserService {
}
}

static Future<List<OtherUser>> searchUsers(String query) async {
static Future<List<User>> searchUsers(String query) async {
try {
http.Response response = await http.get(
Uri.parse(
'${EnvVariables.uri}/users/search?query=${Uri.encodeComponent(query)}'),
);
List<OtherUser> users = [];
log('Searching users: ${response.body}');
List<User> users = [];

for (var user in json.decode(response.body)) {
users.add(OtherUser.fromMap(user));
users.add(User.fromMap(user));
}
return users;
} catch (e) {
Expand Down
2 changes: 1 addition & 1 deletion client/lib/features/friends/view/friends_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class FriendsScreen extends StatelessWidget {
itemBuilder: (context, index) {
final friend = model.searchedUsers[index];
return UserSearchWidget(
username: friend.username,
user: friend,
);
},
);
Expand Down
8 changes: 5 additions & 3 deletions client/lib/features/friends/view/user_profile_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import 'package:georeal/features/friends/widgets/profile_layout.dart';
import 'package:georeal/features/geo_sphere/view_model/geo_sphere_view_model.dart';
import 'package:georeal/features/geo_sphere/widgets/geo_sphere_widget.dart';
import 'package:georeal/global_variables.dart';
import 'package:georeal/models/other_user.dart';
import 'package:georeal/models/user.dart';
import 'package:provider/provider.dart';

class UserProfileScreen extends StatefulWidget {
final OtherUser user;
final User user;
const UserProfileScreen({
super.key,
required this.user,
Expand Down Expand Up @@ -44,7 +44,9 @@ class _UserProfileScreenState extends State<UserProfileScreen> {
body: SafeArea(
child: Column(
children: [
const ProfileLayout(),
ProfileLayout(
user: widget.user,
),
Expanded(
child: Consumer<GeoSphereViewModel>(
builder: (context, geoSphereViewModel, child) {
Expand Down
11 changes: 5 additions & 6 deletions client/lib/features/friends/view_model/friend_view_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:georeal/features/friends/services/user_service.dart';
import 'package:georeal/models/other_user.dart';
import 'package:georeal/models/user.dart';

class FriendViewModel extends ChangeNotifier {
List<OtherUser> _searchedUsers = [];
OtherUser? _selectedUser;
List<User> _searchedUsers = [];
User? _selectedUser;
TextEditingController searchController = TextEditingController();

List<OtherUser> get searchedUsers => _searchedUsers;
OtherUser? get selectedUser => _selectedUser;
List<User> get searchedUsers => _searchedUsers;
User? get selectedUser => _selectedUser;

void fetchUsers() async {
try {
Expand Down Expand Up @@ -41,7 +41,6 @@ class FriendViewModel extends ChangeNotifier {
Future<void> searchUsers() async {
try {
_searchedUsers = await UserService.searchUsers(searchController.text);
log(_searchedUsers.toString(), name: 'Searched users');
notifyListeners();
} catch (e) {
log(e.toString(), name: 'searchUsers');
Expand Down
12 changes: 9 additions & 3 deletions client/lib/features/friends/widgets/profile_layout.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import 'package:flutter/material.dart';
import 'package:georeal/common/profile_photo.dart';
import 'package:georeal/features/friends/view_model/friend_view_model.dart';
import 'package:georeal/models/user.dart';
import 'package:georeal/providers/user_provider';
import 'package:provider/provider.dart';

class ProfileLayout extends StatefulWidget {
const ProfileLayout({super.key});
final User user;
const ProfileLayout({super.key, required this.user});

@override
State<ProfileLayout> createState() => _ProfileLayoutState();
Expand All @@ -26,7 +28,7 @@ class _ProfileLayoutState extends State<ProfileLayout> {
senderUsername, viewModel.selectedUser!.id);
setState(() => _isRequested = true);
} else {
// Handle error or invalid state
// TODO: Handle error or invalid state
}
} finally {
setState(() => _isProcessing = false);
Expand All @@ -45,7 +47,11 @@ class _ProfileLayoutState extends State<ProfileLayout> {
children: [
ProfilePhoto(
radius: 40,
image: Image.asset("assets/images/profile_photo.jpg"),
image: widget.user.profilePhotoUrl != null
? Image.network(widget.user.profilePhotoUrl!)
: const Image(
image: AssetImage('assets/images/default_profile.png'),
),
),
Column(
children: [
Expand Down
24 changes: 16 additions & 8 deletions client/lib/features/friends/widgets/user_search_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@ import 'package:georeal/common/profile_photo.dart';
import 'package:georeal/features/friends/view/user_profile_screen.dart';
import 'package:georeal/features/friends/view_model/friend_view_model.dart';
import 'package:georeal/global_variables.dart';
import 'package:georeal/models/user.dart';
import 'package:georeal/providers/user_provider';
import 'package:provider/provider.dart';

class UserSearchWidget extends StatelessWidget {
final String username;
class UserSearchWidget extends StatefulWidget {
final User user;

const UserSearchWidget({super.key, required this.username});
const UserSearchWidget({super.key, required this.user});

@override
State<UserSearchWidget> createState() => _UserSearchWidgetState();
}

class _UserSearchWidgetState extends State<UserSearchWidget> {
@override
Widget build(BuildContext context) {
return GestureDetector(
Expand All @@ -26,11 +32,15 @@ class UserSearchWidget extends StatelessWidget {
children: [
ProfilePhoto(
radius: 20,
image: Image.asset("assets/images/profile_photo.jpg"),
image: widget.user.profilePhotoUrl != null
? Image.network(widget.user.profilePhotoUrl!)
: const Image(
image: AssetImage('assets/images/default_profile.png'),
),
),
const SizedBox(width: 10),
Text(
username,
widget.user.username,
style: const TextStyle(
color: Colors.white, fontWeight: FontWeight.bold),
),
Expand All @@ -48,7 +58,6 @@ class UserSearchWidget extends StatelessWidget {
));
}

await viewModel.getUserByUsername(username, userProvider.user!.id);
if (context.mounted) {
if (viewModel.selectedUser == null) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
Expand All @@ -59,8 +68,7 @@ class UserSearchWidget extends StatelessWidget {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
UserProfileScreen(user: viewModel.selectedUser!),
builder: (context) => UserProfileScreen(user: widget.user),
),
);
}
Expand Down
4 changes: 1 addition & 3 deletions client/lib/features/profile/views/profile_photo_edit.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:georeal/common/profile_photo.dart';
import 'package:georeal/features/profile/view_model/profile_view_model.dart';
Expand All @@ -21,7 +19,7 @@ class ProfilePhotoEditScreen extends StatelessWidget {
final model = Provider.of<ProfileViewModel>(context, listen: false);
final user = Provider.of<UserProvider>(context, listen: false).user!;
model.fetchProfilePhoto(user.id);
log(user.profilePhotoUrl ?? 'No Photo Url');

return Scaffold(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
appBar: AppBar(
Expand Down
1 change: 1 addition & 0 deletions client/lib/features/profile/views/profile_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
@override
Widget build(BuildContext context) {
final user = Provider.of<UserProvider>(context, listen: false).user!;
log(user.profilePhotoUrl ?? "No profile photo", name: "ProfileScreen");
return Scaffold(
appBar: AppBar(
backgroundColor: GlobalVariables.backgroundColor,
Expand Down
19 changes: 15 additions & 4 deletions client/lib/models/user.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:developer';

import 'package:georeal/constants/env_variables.dart';

class User {
Expand All @@ -8,9 +10,9 @@ class User {
final int numPlaces;
final int numPosts;
final int numFriends;
String?
profilePhotoUrl; // Assuming profile photo is managed separately or not directly included in this model
// Assuming lastLocation, places, posts, and friends are managed separately or not directly included in this model
String? profilePhotoUrl;
List<int>?
friendsIds; // IDs of friends, to be used primarily for the logged-in user

User({
required this.id,
Expand All @@ -21,25 +23,33 @@ class User {
this.numPlaces = 0,
this.numPosts = 0,
this.numFriends = 0,
this.friendsIds,
});

factory User.fromMap(Map<String, dynamic> data) {
log(data.toString(), name: 'User.fromMap');
String? profilePhotoPath = data['profile_photo'];
String? fullProfilePhotoUrl = profilePhotoPath != null
? '${EnvVariables.uri}$profilePhotoPath'
: null;
return User(
id: data['id'],
id: data['user_id'],
username: data['username'],
email: data['email'],
name: data['name'],
numPlaces: data['num_places'] ?? 0,
numPosts: data['num_posts'] ?? 0,
numFriends: data['num_friends'] ?? 0,
profilePhotoUrl: fullProfilePhotoUrl,
friendsIds: data['friends_ids']?.cast<
int>(), // Assuming `friends_ids` is part of the data map when applicable
);
}

bool isFriend(int userId) {
return friendsIds?.contains(userId) ?? false;
}

Map<String, dynamic> toMap() {
return {
'id': id,
Expand All @@ -50,6 +60,7 @@ class User {
'num_posts': numPosts,
'num_friends': numFriends,
'profile_photo': profilePhotoUrl,
'friends_ids': friendsIds,
};
}
}
3 changes: 3 additions & 0 deletions georeal/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class User(db.Model):
num_posts = db.Column(db.Integer, default=0)
num_friends = db.Column(db.Integer, default=0)

def get_friends_ids(self):
return [friend.id for friend in self.friends.all()]

class Geofence(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
Expand Down
Loading

0 comments on commit 4f1fc05

Please sign in to comment.