Skip to content

Commit

Permalink
Add pagination (#152)
Browse files Browse the repository at this point in the history
* Add list pagination

* Add pagination in team matches

* Fix lint

* Add ball-by-ball pagination

* fix lint

* fix lint

---------

Co-authored-by: sidhdhi canopas <[email protected]>
  • Loading branch information
cp-mayank and cp-sidhdhi-p authored Dec 20, 2024
1 parent 9c95f6d commit 6c45fa7
Show file tree
Hide file tree
Showing 18 changed files with 317 additions and 200 deletions.
21 changes: 15 additions & 6 deletions data/lib/service/ball_score/ball_score_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,21 @@ class BallScoreService {
}
}

Stream<List<BallScoreChange>> streamBallScoresByInningIds(
List<String> inningIds,
) {
if (inningIds.isEmpty) return const Stream.empty();
return _ballScoreCollection
.where(FireStoreConst.inningId, whereIn: inningIds)
Stream<List<BallScoreChange>> streamBallScoresByInningIds({
required List<String> inningIds,
int? limit,
}) {
if (inningIds.isEmpty) return Stream.value([]);

var query =
_ballScoreCollection.where(FireStoreConst.inningId, whereIn: inningIds);
if (limit != null) {
query = query
.orderBy(FireStoreConst.scoreTime, descending: true)
.limit(limit);
}

return query
.snapshots()
.map(
(event) => event.docChanges
Expand Down
23 changes: 17 additions & 6 deletions data/lib/service/match/match_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,10 @@ class MatchService {
.catchError((error, stack) => throw AppError.fromError(error, stack));
}

Stream<List<MatchModel>> streamUserRelatedMatches(String userId) {
Stream<List<MatchModel>> streamUserRelatedMatches({
required String userId,
int limit = 10,
}) {
final filter = Filter.or(
Filter(FireStoreConst.createdBy, isEqualTo: userId),
Filter(FireStoreConst.players, arrayContains: userId),
Expand All @@ -159,6 +162,8 @@ class MatchService {

return _matchCollection
.where(filter)
.orderBy(FieldPath.documentId)
.limit(limit)
.snapshots()
.asyncMap((snapshot) async {
return await Future.wait(
Expand Down Expand Up @@ -186,23 +191,27 @@ class MatchService {
}).handleError((error, stack) => throw AppError.fromError(error, stack));
}

Stream<List<MatchModel>> streamMatchesByTeamId(String teamId) {
Stream<List<MatchModel>> streamMatchesByTeamId({
required String teamId,
int limit = 10,
}) {
return _matchCollection
.where(FireStoreConst.teamIds, arrayContains: teamId)
.orderBy(FieldPath.documentId)
.limit(limit)
.snapshots()
.asyncMap((snapshot) async {
return await Future.wait(
snapshot.docs.map((mainDoc) async {
final match = mainDoc.data();

final List<MatchTeamModel> teams = await getTeamsList(match.teams);
return match.copyWith(teams: teams);
}).toList(),
);
}).handleError((error, stack) => throw AppError.fromError(error, stack));
}

Stream<List<MatchModel>> streamActiveRunningMatches() {
Stream<List<MatchModel>> streamActiveRunningMatches({int limit = 10}) {
final DateTime now = DateTime.now();
final DateTime oneAndHalfHoursAgo =
now.subtract(Duration(hours: 1, minutes: 30));
Expand All @@ -215,6 +224,7 @@ class MatchService {
);
return _matchCollection
.where(filter)
.limit(limit)
.snapshots()
.asyncMap((snapshot) async {
return await Future.wait(
Expand All @@ -228,7 +238,7 @@ class MatchService {
}).handleError((error, stack) => throw AppError.fromError(error, stack));
}

Stream<List<MatchModel>> streamUpcomingMatches() {
Stream<List<MatchModel>> streamUpcomingMatches({int limit = 10}) {
final DateTime now = DateTime.now();
final startOfDay = DateTime(now.year, now.month, now.day);
final DateTime aMonthAfter = DateTime(now.year, now.month + 1, now.day);
Expand All @@ -249,6 +259,7 @@ class MatchService {
);
return _matchCollection
.where(filter)
.limit(limit)
.snapshots()
.asyncMap((snapshot) async {
return await Future.wait(
Expand Down Expand Up @@ -655,7 +666,7 @@ class MatchService {

Stream<List<MatchModel>> streamMatchesByIds(List<String> matchIds) {
try {
if (matchIds.isEmpty) return Stream.empty();
if (matchIds.isEmpty) return Stream.value([]);
return _matchCollection
.where(FieldPath.documentId, whereIn: matchIds)
.snapshots()
Expand Down
9 changes: 7 additions & 2 deletions data/lib/service/team/team_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -87,20 +87,25 @@ class TeamService {
}).catchError((error, stack) => throw AppError.fromError(error, stack));
}

Stream<List<TeamModel>> streamUserRelatedTeams(String userId) {
Stream<List<TeamModel>> streamUserRelatedTeams({
required String userId,
int limit = 10,
}) {
final currentPlayer = TeamPlayer(id: userId);

final playerContains = [
currentPlayer.copyWith(role: TeamPlayerRole.admin).toJson(),
currentPlayer.copyWith(role: TeamPlayerRole.player).toJson(),
];

final filter = Filter.or(
Filter(FireStoreConst.createdBy, isEqualTo: userId),
Filter(FireStoreConst.teamPlayers, arrayContainsAny: playerContains),
);

return _teamsCollection
.where(filter)
.orderBy(FieldPath.documentId)
.limit(limit)
.snapshots()
.asyncMap((snapshot) async {
final teams = await Future.wait(
Expand Down
1 change: 1 addition & 0 deletions data/lib/utils/constant/firestore_constant.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class FireStoreConst {
static const String batsmanId = "batsman_id";
static const String wicketTakerId = "wicket_taker_id";
static const String playerOutId = "player_out_id";
static const String scoreTime = "score_time";

// teams field const
static const String players = "players";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ import 'package:khelo/ui/flow/matches/match_detail/components/commentary_ball_su
import 'package:khelo/ui/flow/matches/match_detail/components/commentary_over_overview.dart';
import 'package:khelo/ui/flow/matches/match_detail/components/final_score_view.dart';
import 'package:khelo/ui/flow/matches/match_detail/match_detail_tab_view_model.dart';
import 'package:style/callback/on_visible_callback.dart';
import 'package:style/extensions/context_extensions.dart';
import 'package:style/indicator/progress_indicator.dart';
import 'package:style/text/app_text_style.dart';

import '../../../../../domain/extensions/widget_extension.dart';

class MatchDetailCommentaryView extends ConsumerWidget {
const MatchDetailCommentaryView({super.key});

Expand All @@ -39,10 +42,38 @@ class MatchDetailCommentaryView extends ConsumerWidget {
}

return (state.overList.isNotEmpty)
? ListView(
? ListView.builder(
padding:
context.mediaQueryPadding + const EdgeInsets.only(bottom: 24),
children: _buildCommentaryList(context, state),
itemCount: 1 + state.overList.length + 1,
itemBuilder: (context, index) {
if (index == 0) {
return const Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: FinalScoreView(),
);
}
if (index < state.overList.length + 1) {
final overSummaryIndex = state.overList.length - index;
final overSummary = state.overList[overSummaryIndex];
final nextOverSummary =
state.overList.elementAtOrNull(overSummaryIndex + 1);
final team = _getTeamByTeamId(state, overSummary.team_id);

return _buildCommentaryItem(
context,
overSummary: overSummary,
team: team,
nextOverSummary: nextOverSummary,
);
}
return OnVisibleCallback(
onVisible: () => runPostFrame(notifier.loadBallScores),
child: (state.loadingBallScoreMore && state.overList.isNotEmpty)
? const Center(child: AppProgressIndicator())
: const SizedBox(),
);
},
)
: EmptyScreen(
title: context.l10n.match_detail_match_not_started_error_title,
Expand All @@ -51,61 +82,65 @@ class MatchDetailCommentaryView extends ConsumerWidget {
);
}

List<Widget> _buildCommentaryList(
BuildContext context,
MatchDetailTabState state,
) {
Widget _buildCommentaryItem(
BuildContext context, {
required OverSummary overSummary,
required TeamModel? team,
OverSummary? nextOverSummary,
}) {
List<Widget> children = [];

children.add(const Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0),
child: FinalScoreView(),
));
for (int index = state.overList.length - 1; index >= 0; index--) {
final overSummary = state.overList[index];
final team = _getTeamByTeamId(state, overSummary.team_id);

final nextOverSummary = state.overList.elementAtOrNull(index + 1);
if (nextOverSummary != null &&
nextOverSummary.overNumber != overSummary.overNumber) {
children.add(Padding(
// Add BowlerSummaryView if applicable
if (nextOverSummary != null &&
nextOverSummary.overNumber != overSummary.overNumber) {
children.add(
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: BowlerSummaryView(
bowlerSummary: nextOverSummary.bowlerStatAtStart,
isForBowlerIntro: true,
),
));
}
),
);
}

if ((overSummary.balls.lastOrNull?.isLegalDelivery() ?? false) &&
overSummary.balls.lastOrNull?.ball_number == 6 &&
nextOverSummary?.inning_id == overSummary.inning_id) {
children
.add(CommentaryOverOverview(overSummary: overSummary, team: team));
} else if (nextOverSummary != null &&
nextOverSummary.inning_id != overSummary.inning_id) {
children.addAll([
_inningOverview(context,
teamName: team?.name ?? "", targetRun: overSummary.totalRuns + 1),
CommentaryOverOverview(overSummary: overSummary, team: team),
]);
}
// Add CommentaryOverOverview or InningOverview if applicable
if ((overSummary.balls.lastOrNull?.isLegalDelivery() ?? false) &&
overSummary.balls.lastOrNull?.ball_number == 6 &&
nextOverSummary?.inning_id == overSummary.inning_id) {
children
.add(CommentaryOverOverview(overSummary: overSummary, team: team));
} else if (nextOverSummary != null &&
nextOverSummary.inning_id != overSummary.inning_id) {
children.addAll([
_inningOverview(
context,
teamName: team?.name ?? "",
targetRun: overSummary.totalRuns + 1,
),
CommentaryOverOverview(overSummary: overSummary, team: team),
]);
}

for (final ball in overSummary.balls.reversed) {
children.addAll([
CommentaryBallSummary(
ball: ball,
overSummary: overSummary,
showBallScore:
ball.is_four || ball.is_six || ball.wicket_taker_id != null,
),
if (ball != overSummary.balls.first) ...[
Divider(color: context.colorScheme.outline),
// Add CommentaryBallSummary for each ball
children.addAll(
overSummary.balls.reversed.map(
(ball) => Column(
children: [
CommentaryBallSummary(
ball: ball,
overSummary: overSummary,
showBallScore:
ball.is_four || ball.is_six || ball.wicket_taker_id != null,
),
if (ball != overSummary.balls.first)
Divider(color: context.colorScheme.outline),
],
]);
}
}
return children;
),
),
);

return Column(children: children);
}

TeamModel? _getTeamByTeamId(MatchDetailTabState state, String teamId) {
Expand Down
Loading

0 comments on commit 6c45fa7

Please sign in to comment.