Skip to content

Commit dd39f43

Browse files
committed
rfac: refactor contest, feed bloc
1 parent 865ab9b commit dd39f43

9 files changed

Lines changed: 51 additions & 28 deletions

File tree

lib/domain/repositories/cp_repository.dart

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'dart:convert';
22

3+
import '../../data/constants/strings.dart';
34
import '../../data/services/remote/api_service.dart';
45
import '../models/activity_details.dart';
56
import '../models/contest.dart';
@@ -38,7 +39,8 @@ class CPRepository {
3839
if (response['status_code'] == 200) {
3940
return Contest.fromJson(response['data']);
4041
}
41-
return null;
42+
43+
throw Exception(AppStrings.genericError);
4244
}
4345

4446
static Future<List<Feed>?> getFeed({DateTime? before}) async {
@@ -62,7 +64,8 @@ class CPRepository {
6264
response['data'].map((e) => Feed.fromJson(e)),
6365
);
6466
}
65-
return null;
67+
68+
throw Exception(AppStrings.genericError);
6669
}
6770

6871
static Future<List<Submission>?> getSubmissionList(String uid) async {

lib/presentation/contests/bloc/contests_bloc.dart

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import '../../../data/services/local/storage_service.dart';
77
import '../../../data/services/remote/notification_service.dart';
88
import '../../../domain/models/contest.dart';
99
import '../../../domain/models/contest_filter.dart';
10+
import '../../../domain/models/status.dart';
1011
import '../../../domain/repositories/cp_repository.dart';
12+
import '../../../utils/snackbar.dart';
1113

1214
part 'contests_event.dart';
1315
part 'contests_state.dart';
@@ -22,14 +24,22 @@ class ContestsBloc extends Bloc<ContestsEvent, ContestsState> {
2224
}
2325

2426
void _fetchContests(FetchContests event, Emitter<ContestsState> emit) async {
25-
final contest = await CPRepository.contestList();
27+
Contest? contest;
28+
try {
29+
contest = await CPRepository.contestList();
30+
} on Exception catch (_) {
31+
showSnackBar(message: AppStrings.genericError);
32+
emit(state.copyWith(status: const Status.error(AppStrings.genericError)));
33+
return;
34+
}
35+
2636
_ongoing = [...?contest?.ongoing];
2737
_upcoming = [...?contest?.upcoming];
2838
applyFilter();
2939
final contests = [..._filteredUpcoming, ..._filteredOngoing];
3040
emit(state.copyWith(
3141
contests: contests,
32-
isLoading: false,
42+
status: const Status(),
3343
filter: _filter,
3444
));
3545
}

lib/presentation/contests/bloc/contests_state.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ part of 'contests_bloc.dart';
33
@freezed
44
class ContestsState extends Equatable with _$ContestsState {
55
const factory ContestsState({
6-
@Default(true) bool isLoading,
6+
@Default(Status.loading()) Status status,
77
@Default([]) List contests,
88
ContestFilter? filter,
99
int? duration,
@@ -13,5 +13,5 @@ class ContestsState extends Equatable with _$ContestsState {
1313
const ContestsState._();
1414

1515
@override
16-
List<Object?> get props => [isLoading, contests, filter, duration, updateIdx];
16+
List<Object?> get props => [status, contests, filter, duration, updateIdx];
1717
}

lib/presentation/contests/contests_screen.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
22
import 'package:flutter_bloc/flutter_bloc.dart';
33

44
import '../../domain/models/contest.dart';
5+
import '../../domain/models/status.dart';
56
import '../components/widgets/empty_state.dart';
67
import 'bloc/contests_bloc.dart';
78
import 'widgets/contest_card.dart';
@@ -22,7 +23,7 @@ class ContestsScreen extends StatelessWidget {
2223
),
2324
body: BlocBuilder<ContestsBloc, ContestsState>(
2425
builder: (context, state) {
25-
if (state.isLoading) {
26+
if (state.status is Loading || state.status is Error) {
2627
return const LoadingState();
2728
}
2829
if (state.contests.isEmpty) {

lib/presentation/contests/widgets/contest_card.dart

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ class ContestCard extends StatelessWidget {
120120
child: Text(
121121
'Set Reminder',
122122
style: AppStyles.h6.copyWith(
123-
color: AppColors.primaryBlack,
123+
color: AppColors.grey3,
124124
),
125125
textAlign: TextAlign.center,
126126
),
@@ -146,7 +146,7 @@ class ContestCard extends StatelessWidget {
146146
child: Text(
147147
'You will be reminded before the contest starts. Set the timer',
148148
style: AppStyles.h6.copyWith(
149-
color: AppColors.primaryBlack,
149+
color: AppColors.grey3,
150150
fontSize: 12.sp,
151151
),
152152
textAlign: TextAlign.center,
@@ -181,8 +181,7 @@ class ContestCard extends StatelessWidget {
181181
AppStyles.h6.copyWith(
182182
color: index == value
183183
? AppColors.primary
184-
: AppColors
185-
.primaryBlack,
184+
: AppColors.grey3,
186185
),
187186
);
188187
},

lib/presentation/feed/bloc/feed_bloc.dart

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ import 'package:flutter_bloc/flutter_bloc.dart';
44
import 'package:freezed_annotation/freezed_annotation.dart';
55
import 'package:get/get.dart';
66

7+
import '../../../data/constants/strings.dart';
78
import '../../../domain/models/feed.dart';
89
import '../../../domain/models/grouped_feed.dart';
10+
import '../../../domain/models/status.dart';
911
import '../../../domain/repositories/cp_repository.dart';
12+
import '../../../utils/snackbar.dart';
1013

1114
part 'feed_bloc.freezed.dart';
1215
part 'feed_state.dart';
@@ -23,15 +26,21 @@ class FeedBloc extends Bloc<FeedEvent, FeedState> {
2326
if (event.fetchNext) {
2427
emit(state.copyWith(isFetchingNext: true));
2528
} else {
26-
emit(state.copyWith(isLoading: true));
29+
emit(state.copyWith(status: const Status.loading()));
2730
}
2831

29-
feeds = await CPRepository.getFeed(
30-
before: event.fetchNext
31-
? groupedFeeds.last.submissions?.last.createdAt
32-
: null,
33-
) ??
34-
<Feed>[];
32+
try {
33+
feeds = await CPRepository.getFeed(
34+
before: event.fetchNext
35+
? groupedFeeds.last.submissions?.last.createdAt
36+
: null,
37+
) ??
38+
<Feed>[];
39+
} on Exception catch (_) {
40+
showSnackBar(message: AppStrings.genericError);
41+
emit(state.copyWith(status: const Status.error(AppStrings.genericError)));
42+
return;
43+
}
3544

3645
if (feeds.isEmpty) _allLoaded = true;
3746

@@ -56,7 +65,7 @@ class FeedBloc extends Bloc<FeedEvent, FeedState> {
5665

5766
emit(
5867
state.copyWith(
59-
isLoading: false,
68+
status: const Status(),
6069
feeds: [...groupedFeeds],
6170
isFetchingNext: false,
6271
allLoaded: _allLoaded,

lib/presentation/feed/bloc/feed_state.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ part of 'feed_bloc.dart';
33
@freezed
44
class FeedState with _$FeedState {
55
const factory FeedState({
6-
@Default(true) bool isLoading,
6+
@Default(Status.loading()) Status status,
77
@Default(false) bool isFetchingNext,
88
@Default(false) bool allLoaded,
99
@Default([]) List<GroupedFeed> feeds,

lib/presentation/feed/feed_screen.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:flutter_svg/flutter_svg.dart';
55

66
import '../../data/constants/assets.dart';
77
import '../../data/constants/colors.dart';
8+
import '../../domain/models/status.dart';
89
import '../components/widgets/empty_state.dart';
910
import '../contests/widgets/loading_state.dart';
1011
import 'bloc/feed_bloc.dart';
@@ -40,7 +41,7 @@ class FeedScreen extends StatelessWidget {
4041
),
4142
body: BlocBuilder<FeedBloc, FeedState>(
4243
builder: (context, state) {
43-
if (state.isLoading) {
44+
if (state.status is Loading || state.status is Error) {
4445
return const LoadingState();
4546
}
4647

pubspec.lock

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -412,13 +412,6 @@ packages:
412412
url: "https://pub.dartlang.org"
413413
source: hosted
414414
version: "1.0.4"
415-
flutter_plugin_android_lifecycle:
416-
dependency: transitive
417-
description:
418-
name: flutter_plugin_android_lifecycle
419-
url: "https://pub.dartlang.org"
420-
source: hosted
421-
version: "2.0.5"
422415
flutter_local_notifications:
423416
dependency: "direct main"
424417
description:
@@ -447,6 +440,13 @@ packages:
447440
url: "https://pub.dartlang.org"
448441
source: hosted
449442
version: "2.0.0"
443+
flutter_plugin_android_lifecycle:
444+
dependency: transitive
445+
description:
446+
name: flutter_plugin_android_lifecycle
447+
url: "https://pub.dartlang.org"
448+
source: hosted
449+
version: "2.0.5"
450450
flutter_screenutil:
451451
dependency: "direct main"
452452
description:

0 commit comments

Comments
 (0)