Skip to content

Commit 722958b

Browse files
committed
feat: integrate other tabs with profile
Signed-off-by: Aman <aman2@me.iitr.ac.in>
1 parent cf7956f commit 722958b

13 files changed

Lines changed: 282 additions & 187 deletions

File tree

lib/presentation/contests/contests_screen.dart

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -14,44 +14,41 @@ class ContestsScreen extends StatelessWidget {
1414

1515
@override
1616
Widget build(BuildContext context) {
17-
return BlocProvider<ContestsBloc>(
18-
create: (_) => ContestsBloc()..init(),
19-
child: Scaffold(
20-
appBar: const PreferredSize(
21-
preferredSize: Size.fromHeight(kToolbarHeight),
22-
child: ContestHeader(),
23-
),
24-
body: BlocBuilder<ContestsBloc, ContestsState>(
25-
builder: (context, state) {
26-
if (state.status is Loading || state.status is Error) {
27-
return const LoadingState();
28-
}
29-
if (state.contests.isEmpty) {
30-
return const EmptyState(
31-
description: 'No contests found, please adjust your filters!',
32-
);
33-
}
34-
return ListView.builder(
35-
itemCount: state.contests.length,
36-
itemBuilder: (context, index) {
37-
final isReminderSet = context
38-
.read<ContestsBloc>()
39-
.reminderSet(state.contests[index].name);
40-
if (state.contests[index] is Ongoing) {
41-
return ContestCard(
42-
isReminderSet: isReminderSet,
43-
ongoing: state.contests[index],
44-
);
45-
}
46-
17+
return Scaffold(
18+
appBar: const PreferredSize(
19+
preferredSize: Size.fromHeight(kToolbarHeight),
20+
child: ContestHeader(),
21+
),
22+
body: BlocBuilder<ContestsBloc, ContestsState>(
23+
builder: (context, state) {
24+
if (state.status is Loading || state.status is Error) {
25+
return const LoadingState();
26+
}
27+
if (state.contests.isEmpty) {
28+
return const EmptyState(
29+
description: 'No contests found, please adjust your filters!',
30+
);
31+
}
32+
return ListView.builder(
33+
itemCount: state.contests.length,
34+
itemBuilder: (context, index) {
35+
final isReminderSet = context
36+
.read<ContestsBloc>()
37+
.reminderSet(state.contests[index].name);
38+
if (state.contests[index] is Ongoing) {
4739
return ContestCard(
4840
isReminderSet: isReminderSet,
49-
upcoming: state.contests[index],
41+
ongoing: state.contests[index],
5042
);
51-
},
52-
);
53-
},
54-
),
43+
}
44+
45+
return ContestCard(
46+
isReminderSet: isReminderSet,
47+
upcoming: state.contests[index],
48+
);
49+
},
50+
);
51+
},
5552
),
5653
);
5754
}

lib/presentation/feed/widgets/feed_card.dart

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:core';
22

33
import 'package:flutter/material.dart';
4+
import 'package:flutter_bloc/flutter_bloc.dart';
45
import 'package:flutter_screenutil/flutter_screenutil.dart';
56
import 'package:flutter_svg/flutter_svg.dart';
67
import 'package:flutter_web_browser/flutter_web_browser.dart';
@@ -11,6 +12,8 @@ import '../../../data/constants/colors.dart';
1112
import '../../../domain/models/grouped_feed.dart';
1213
import '../../../utils/feed_util.dart';
1314
import '../../../utils/platform_util.dart';
15+
import '../../home/bloc/home_bloc.dart';
16+
import '../../profile/bloc/profile_bloc.dart';
1417

1518
class FeedCard extends StatelessWidget {
1619
FeedCard({
@@ -33,7 +36,13 @@ class FeedCard extends StatelessWidget {
3336
children: <Widget>[
3437
GestureDetector(
3538
onTap: () {
36-
// TODO(aman-singh7): Integrate to profile
39+
context
40+
.read<ProfileBloc>()
41+
.add(FetchDetails(userId: feed.userId));
42+
43+
context
44+
.read<HomeBloc>()
45+
.add(const BottomNavItemPressed(index: 3));
3746
},
3847
child: Padding(
3948
padding: EdgeInsets.only(right: 10.w),

lib/presentation/home/bloc/home_bloc.dart

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import 'package:flutter/widgets.dart';
33
import 'package:flutter_bloc/flutter_bloc.dart';
44
import 'package:freezed_annotation/freezed_annotation.dart';
55

6+
import '../../../data/services/local/storage_service.dart';
7+
import '../../../domain/repositories/user_repository.dart';
68
import '../../contests/contests_screen.dart';
79
import '../../feed/feed_screen.dart';
810
import '../../profile/profile_screen.dart';
@@ -18,7 +20,13 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
1820
}
1921
late final List<Widget> screens;
2022

21-
void init() {
23+
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+
}
2230
screens = <Widget>[
2331
const FeedScreen(),
2432
const ContestsScreen(),

lib/presentation/home/home_screen.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import 'package:flutter_bloc/flutter_bloc.dart';
33

44
import '../../data/constants/assets.dart';
55
import '../../data/constants/colors.dart';
6+
import '../contests/bloc/contests_bloc.dart';
67
import '../feed/bloc/feed_bloc.dart';
8+
import '../profile/bloc/profile_bloc.dart';
9+
import '../search/bloc/search_bloc.dart';
710
import 'bloc/home_bloc.dart';
811
import 'widgets/nav_bar_item.dart';
912

@@ -20,6 +23,15 @@ class HomeScreen extends StatelessWidget {
2023
BlocProvider(
2124
create: (context) => FeedBloc()..init(),
2225
),
26+
BlocProvider(
27+
create: (context) => ContestsBloc()..init(),
28+
),
29+
BlocProvider(
30+
create: (context) => SearchBloc()..add(const Init()),
31+
),
32+
BlocProvider(
33+
create: (context) => ProfileBloc()..add(const FetchDetails()),
34+
),
2335
],
2436
child: BlocBuilder<HomeBloc, HomeState>(
2537
builder: (context, state) {
@@ -74,6 +86,11 @@ class HomeScreen extends StatelessWidget {
7486
label: 'Profile',
7587
isActive: state.selectedIndex == 3,
7688
callback: () {
89+
// Set to default
90+
if (!context.read<ProfileBloc>().isSelfProfile) {
91+
context.read<ProfileBloc>().add(const FetchDetails());
92+
}
93+
7794
context
7895
.read<HomeBloc>()
7996
.add(const BottomNavItemPressed(index: 3));

lib/presentation/profile/bloc/profile_bloc.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
4242
List<ActivityDetails>? _activityDetails;
4343
// TODO(aman-singh7): Throw specific Error
4444
try {
45+
if (_user == null) throw Exception('User not found!!');
4546
_followingList = await UserRepository.getFollowingList();
4647

4748
_subStats = await UserRepository.getSubmissionStatusData(_user!.id!);
@@ -72,7 +73,7 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
7273
user: _user,
7374
following: _followingList,
7475
submissionStatus: _subStats,
75-
personalProfile: event.userId.isEmpty,
76+
personalProfile: isSelfProfile,
7677
isFollowing: _isFollowing,
7778
currentYear: _currentYear,
7879
currentTriplet: _currentTriplet,
@@ -163,6 +164,8 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
163164
return const Color(0xFFEEEEEE);
164165
}
165166

167+
bool get isSelfProfile => _user?.id == StorageService.user?.id;
168+
166169
int _currentYear = DateTime.now().year;
167170
int _currentTriplet = DateTime.now().month ~/ 3;
168171
List<Following>? _followingList;

lib/presentation/profile/profile_screen.dart

Lines changed: 46 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -20,60 +20,57 @@ class ProfileScreen extends StatelessWidget {
2020

2121
@override
2222
Widget build(BuildContext context) {
23-
return BlocProvider(
24-
create: (context) => ProfileBloc()..add(const FetchDetails()),
25-
child: BlocConsumer<ProfileBloc, ProfileState>(
26-
listenWhen: (previous, current) =>
27-
previous.status.hashCode != current.status.hashCode,
28-
listener: (context, state) {
29-
if (state.status is Error) {
30-
showSnackBar(message: AppStrings.genericError);
31-
}
32-
},
33-
// When Loading state changes
34-
buildWhen: (previous, current) =>
35-
previous.status.hashCode != current.status.hashCode ||
36-
previous.showFollowing ^ current.showFollowing,
37-
builder: (context, state) {
38-
if (state.status is Loading || state.status is Error) {
39-
return const ProfileLoadingState();
40-
}
23+
return BlocConsumer<ProfileBloc, ProfileState>(
24+
listenWhen: (previous, current) =>
25+
previous.status.hashCode != current.status.hashCode,
26+
listener: (context, state) {
27+
if (state.status is Error) {
28+
showSnackBar(message: AppStrings.genericError);
29+
}
30+
},
31+
// When Loading state changes
32+
buildWhen: (previous, current) =>
33+
previous.status.hashCode != current.status.hashCode ||
34+
previous.showFollowing ^ current.showFollowing,
35+
builder: (context, state) {
36+
if (state.status is Loading || state.status is Error) {
37+
return const ProfileLoadingState();
38+
}
4139

42-
if (state.showFollowing) return const FollowingView();
40+
if (state.showFollowing) return const FollowingView();
4341

44-
return ListView(
45-
children: [
46-
const ProfileHeader(),
47-
Padding(
48-
padding: EdgeInsets.fromLTRB(16.w, 24.h, 0, 8.h),
49-
child: Text(
50-
'Accuracy',
51-
style: AppStyles.h1.copyWith(fontSize: 15.sp),
52-
),
42+
return ListView(
43+
children: [
44+
const ProfileHeader(),
45+
Padding(
46+
padding: EdgeInsets.fromLTRB(16.w, 24.h, 0, 8.h),
47+
child: Text(
48+
'Accuracy',
49+
style: AppStyles.h1.copyWith(fontSize: 15.sp),
5350
),
54-
const AccuracyDisplay(),
55-
SizedBox(height: 30.h),
56-
Padding(
57-
padding: EdgeInsets.only(left: 16.w, top: 24.h),
58-
child: Text(
59-
'Number of question solved',
60-
style: AppStyles.h1.copyWith(fontSize: 15.sp),
61-
),
51+
),
52+
const AccuracyDisplay(),
53+
SizedBox(height: 30.h),
54+
Padding(
55+
padding: EdgeInsets.only(left: 16.w, top: 24.h),
56+
child: Text(
57+
'Number of question solved',
58+
style: AppStyles.h1.copyWith(fontSize: 15.sp),
6259
),
63-
const QuestionSolved(),
64-
Padding(
65-
padding: EdgeInsets.only(left: 16.w, top: 24.h),
66-
child: Text(
67-
'Status of total Submissions',
68-
style: AppStyles.h1.copyWith(fontSize: 15.sp),
69-
),
60+
),
61+
const QuestionSolved(),
62+
Padding(
63+
padding: EdgeInsets.only(left: 16.w, top: 24.h),
64+
child: Text(
65+
'Status of total Submissions',
66+
style: AppStyles.h1.copyWith(fontSize: 15.sp),
7067
),
71-
const SubmissionDisplay(),
72-
const AcceptanceGraph(),
73-
],
74-
);
75-
},
76-
),
68+
),
69+
const SubmissionDisplay(),
70+
const AcceptanceGraph(),
71+
],
72+
);
73+
},
7774
);
7875
}
7976
}

0 commit comments

Comments
 (0)