Skip to content

Commit 196bf2b

Browse files
committed
feat: implement follow and unfollow
Signed-off-by: Aman <aman2@me.iitr.ac.in>
1 parent 722958b commit 196bf2b

5 files changed

Lines changed: 66 additions & 24 deletions

File tree

lib/data/services/local/storage_service.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class StorageService {
8181
static List<User>? get recentSearches {
8282
try {
8383
return List<User>.from(json
84-
.decode(_get<String>(AppStrings.recentSearchKey)!)
84+
.decode(_get<String>(AppStrings.recentSearchKey) ?? '')
8585
.map((e) => User.fromJson(e)));
8686
} on Exception catch (_) {
8787
return null;

lib/presentation/home/bloc/home_bloc.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,18 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
2121
late final List<Widget> screens;
2222

2323
void init() async {
24-
// Fetch User Details on Startup
25-
try {
26-
StorageService.user = await UserRepository.fetchUserDetails();
27-
} on Exception catch (err) {
28-
debugPrint(err.toString());
29-
}
3024
screens = <Widget>[
3125
const FeedScreen(),
3226
const ContestsScreen(),
3327
const SearchScreen(),
3428
const ProfileScreen(),
3529
];
30+
// Fetch User Details on Startup
31+
try {
32+
StorageService.user = await UserRepository.fetchUserDetails();
33+
} on Exception catch (err) {
34+
debugPrint(err.toString());
35+
}
3636
}
3737

3838
void _changeScreen(BottomNavItemPressed event, Emitter<HomeState> emit) {

lib/presentation/profile/bloc/profile_bloc.dart

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,23 +115,42 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
115115
emit(state.copyWith(
116116
following: _followingList,
117117
showFollowing: event.toShow,
118+
user: _user,
118119
));
119120
}
120121

121-
static Future follow(String userId) async {
122+
Future follow(String userId) async {
122123
final statuscode = await UserRepository.followUser(userId);
123124

124125
if (statuscode != 200) {
125126
throw Exception(AppStrings.genericError);
126127
}
128+
129+
var _tempUser = StorageService.user;
130+
_tempUser = _tempUser?.copyWith(
131+
noOfFollowing: (_tempUser.noOfFollowing ?? 0) + 1,
132+
);
133+
StorageService.user = _tempUser;
134+
if (_user?.id != _tempUser?.id) return;
135+
136+
_user = _tempUser;
127137
}
128138

129-
static Future unfollow(String userId) async {
139+
Future unfollow(String userId) async {
130140
final statuscode = await UserRepository.unfollowUser(userId);
131141

132142
if (statuscode != 200) {
133143
throw Exception(AppStrings.genericError);
134144
}
145+
146+
var _tempUser = StorageService.user;
147+
_tempUser = _tempUser?.copyWith(
148+
noOfFollowing: (_tempUser.noOfFollowing ?? 0) - 1,
149+
);
150+
StorageService.user = _tempUser;
151+
if (_user?.id != _tempUser?.id) return;
152+
153+
_user = _tempUser;
135154
}
136155

137156
// Index -> Index%4

lib/presentation/profile/widgets/following_view.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,12 @@ class FollowingView extends StatelessWidget {
9090
/// to rebuild the whole list
9191
trailing: ValueListenableBuilder<bool>(
9292
valueListenable: _followNotifier,
93-
builder: (context, value, _) {
93+
builder: (_, value, child) {
9494
if (value) {
9595
return FollowingButton(
9696
onTap: () async {
9797
try {
98-
await ProfileBloc.unfollow(user.id);
98+
await context.read<ProfileBloc>().unfollow(user.id);
9999
_followNotifier.value = false;
100100
} on Exception catch (_) {
101101
showSnackBar(message: AppStrings.genericError);
@@ -107,7 +107,7 @@ class FollowingView extends StatelessWidget {
107107
return FollowButton(
108108
onTap: () async {
109109
try {
110-
await ProfileBloc.follow(user.id);
110+
await context.read<ProfileBloc>().follow(user.id);
111111
_followNotifier.value = true;
112112
} on Exception catch (_) {
113113
showSnackBar(message: AppStrings.genericError);

lib/presentation/profile/widgets/profile_header.dart

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class ProfileHeader extends StatelessWidget {
2222
Widget build(BuildContext context) {
2323
return BlocBuilder<ProfileBloc, ProfileState>(
2424
builder: (context, state) {
25+
// Follow Notifier
26+
final _followNotifier = ValueNotifier(state.isFollowing);
2527
return Container(
2628
color: AppColors.primary,
2729
child: Column(
@@ -192,18 +194,39 @@ class ProfileHeader extends StatelessWidget {
192194
vertical: 8.h,
193195
horizontal: 16.w,
194196
),
195-
child: Visibility(
196-
visible: state.isFollowing,
197-
replacement: FollowButton(
198-
onTap: () {
199-
// TODO(aman-singh7): Implement follow
200-
},
201-
),
202-
child: FollowingButton(
203-
onTap: () {
204-
// TODO(aman-singh7): Implement unfollow
205-
},
206-
),
197+
child: ValueListenableBuilder<bool>(
198+
valueListenable: _followNotifier,
199+
builder: (_, value, child) {
200+
if (value) {
201+
return FollowingButton(
202+
onTap: () async {
203+
try {
204+
await context
205+
.read<ProfileBloc>()
206+
.unfollow(state.user!.id!);
207+
_followNotifier.value = false;
208+
} on Exception catch (_) {
209+
showSnackBar(
210+
message: AppStrings.genericError);
211+
}
212+
},
213+
);
214+
}
215+
216+
return FollowButton(
217+
onTap: () async {
218+
try {
219+
await context
220+
.read<ProfileBloc>()
221+
.follow(state.user!.id!);
222+
_followNotifier.value = true;
223+
} on Exception catch (_) {
224+
showSnackBar(
225+
message: AppStrings.genericError);
226+
}
227+
},
228+
);
229+
},
207230
),
208231
),
209232
],

0 commit comments

Comments
 (0)