Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement tournament overview tab #121

Merged
merged 10 commits into from
Oct 23, 2024

Conversation

cp-mayank
Copy link
Collaborator

@cp-mayank cp-mayank commented Oct 16, 2024

  • Implement tournament detail overview tab
overview.webm

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced tournament model with a required end date and new player key statistics.
    • Introduction of a detailed tournament overview tab displaying key stats, featured matches, and team information.
    • Added new localization entries for tournament details and key statistics.
  • Bug Fixes

    • Improved error handling in match and tournament service methods.
  • Chores

    • Upgraded dependencies for flutter_riverpod and hooks_riverpod to the latest versions.

@cp-mayank cp-mayank marked this pull request as ready for review October 18, 2024 05:52
Copy link

coderabbitai bot commented Oct 18, 2024

Walkthrough

The pull request introduces significant updates to the tournament and player statistics models in the Flutter application. Key changes include making the end_date field in TournamentModel required, adding a new keyStats field, and introducing the PlayerKeyStat class for player statistics. The MatchService and TournamentService classes have been modified to enhance data retrieval and processing. Additionally, localization strings have been added, and several UI components have been updated to reflect these changes. Overall, the updates improve data handling and user interaction within the tournament context.

Changes

File Path Change Summary
data/lib/api/tournament/tournament_model.dart - end_date changed from optional to required in TournamentModel.
- Added keyStats field.
- Introduced PlayerKeyStat class with required fields.
- Added PlayerKeyStatListExtensions with getTopKeyStats() method.
data/lib/api/tournament/tournament_model.freezed.dart - Updated TournamentModel to include keyStats.
- Changed end_date from nullable to non-nullable.
- Added PlayerKeyStat class with necessary methods.
data/lib/api/tournament/tournament_model.g.dart - Added JSON serialization for PlayerKeyStat.
- Introduced KeyStatTag enumeration mapping.
data/lib/service/match/match_service.dart - Updated getMatchesByIds to limit match IDs to 10.
- Refactored getTeamsList for efficiency.
- Simplified getPlayerListFromPlayerIds.
data/lib/service/tournament/tournament_service.dart - Added dependency on BallScoreService.
- Introduced getKeyStats method for player statistics.
khelo/assets/locales/app_en.arb - Added new localization entries for tournament details and removed outdated entries.
khelo/lib/components/won_by_message_text.dart - Introduced isTournament boolean property in WonByMessageText.
khelo/lib/domain/formatter/date_formatter.dart - Added relativeTime method for date representation.
- Updated formatDateRange to allow nullable endDate.
khelo/lib/ui/flow/home/home_screen.dart - Updated localization key for "View All" button.
khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_overview_tab.dart - Added TournamentDetailOverviewTab widget for displaying tournament details.
khelo/lib/ui/flow/tournament/detail/tournament_detail_screen.dart - Changed layout structure to include TournamentDetailOverviewTab.
khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.dart - Added dispose method in TournamentDetailStateViewNotifier.
khelo/lib/ui/flow/tournament/tournament_list_screen.dart - Simplified date formatting logic in _scheduleAndTypeView.
style/lib/extensions/date_extensions.dart - Introduced isSameDay method in DateTimeExtensions.
data/lib/api/ball_score/ball_score_model.dart - Added UserStat, BattingStat, BowlingStat, and FieldingStat classes with JSON serialization.
data/lib/api/ball_score/ball_score_model.freezed.dart - Added new classes for user statistics with serialization methods.
data/lib/api/ball_score/ball_score_model.g.dart - Added JSON serialization methods for new statistics classes.
khelo/lib/domain/extensions/enum_extensions.dart - Added getString method in TournamentKeyStatString extension for localized strings.
data/.flutter-plugins-dependencies - Updated date_created and added shared_preferences_android plugin.
data/pubspec.yaml - Updated versions for flutter_riverpod and hooks_riverpod.
khelo/pubspec.yaml - Updated versions for flutter_riverpod and hooks_riverpod.

Possibly related PRs

Suggested reviewers

  • cp-sidhdhi-p

🐰 "In the fields where tournaments play,
New stats and models come out to stay.
With key stats to track and dates that are clear,
We hop into action, spreading good cheer!
For every match and every run,
Our game just got better, oh what fun!" 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

🧹 Outside diff range and nitpick comments (4)
style/lib/extensions/date_extensions.dart (1)

1-1: Verify the necessity of the Material import.

The import statement import 'package:flutter/material.dart'; is present, but it's not immediately clear if it's necessary for this file. The DateUtils class is part of the material library, so this import is required for the isSameDay method. However, for better code organization, consider importing only the specific parts needed.

You could replace the current import with a more specific one:

import 'package:flutter/src/material/date.dart' show DateUtils;

This would make the dependencies of this file more explicit and potentially improve compile times.

khelo/lib/domain/formatter/date_formatter.dart (1)

46-62: LGTM: Well-implemented relative time formatting.

The relativeTime method provides a user-friendly representation of dates. It correctly handles cases for today, tomorrow, and other dates within the same year or different years.

Consider adding localization support for the strings "Today" and "Tomorrow" to make the method more internationalization-friendly. You could use the context parameter to access localized strings:

day = context.l10n.today;
// and
day = context.l10n.tomorrow;
data/lib/service/ball_score/ball_score_service.dart (1)

186-205: LGTM! Consider minor improvements.

The implementation of getPlayerTotalRuns is well-structured and aligns with the class's error handling pattern. Good job on using the Filter.and for efficient querying and the fold operation for summing runs.

Consider the following minor improvements:

  1. Add a comment explaining the purpose of the runsScored > 0 check in the fold operation. For example:

    // Only sum positive run values to exclude any potential negative adjustments
    return runsScored > 0 ? total + runsScored : total;
  2. Add input validation for matchId and playerId at the beginning of the method:

    if (matchId.isEmpty || playerId.isEmpty) {
      throw ArgumentError('matchId and playerId must not be empty');
    }

These changes will improve code readability and robustness.

khelo/lib/ui/flow/tournament/detail/tournament_detail_screen.dart (1)

114-117: LGTM: Addition of TournamentDetailOverviewTab

The changes here effectively implement the new overview tab, which aligns with the PR objective. The const keyword removal is correct as the list now contains a non-constant widget.

Suggestion for improvement:
Consider using a list comprehension or a separate method to generate the tab widgets. This approach would make it easier to add or modify tabs in the future.

For example:

children: [
  for (final tab in _tabs)
    tab.buildWidget(tournament: state.tournament!),
],

Where _tabs could be a list of custom objects that know how to build their respective widgets.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between d7c811c and d5935e3.

📒 Files selected for processing (15)
  • data/lib/api/tournament/tournament_model.dart (3 hunks)
  • data/lib/api/tournament/tournament_model.freezed.dart (14 hunks)
  • data/lib/api/tournament/tournament_model.g.dart (1 hunks)
  • data/lib/service/ball_score/ball_score_service.dart (1 hunks)
  • data/lib/service/match/match_service.dart (1 hunks)
  • data/lib/service/tournament/tournament_service.dart (5 hunks)
  • khelo/assets/locales/app_en.arb (2 hunks)
  • khelo/lib/components/won_by_message_text.dart (2 hunks)
  • khelo/lib/domain/formatter/date_formatter.dart (2 hunks)
  • khelo/lib/ui/flow/home/home_screen.dart (1 hunks)
  • khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_overview_tab.dart (1 hunks)
  • khelo/lib/ui/flow/tournament/detail/tournament_detail_screen.dart (3 hunks)
  • khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.dart (1 hunks)
  • khelo/lib/ui/flow/tournament/tournament_list_screen.dart (1 hunks)
  • style/lib/extensions/date_extensions.dart (1 hunks)
🧰 Additional context used
🔇 Additional comments (32)
style/lib/extensions/date_extensions.dart (1)

6-6: New method isSameDay looks good.

The new isSameDay method is a valuable addition to the DateTimeExtensions. It provides a convenient way to compare dates while ignoring the time component. The use of DateUtils.isSameDay from the Flutter framework ensures consistency with Flutter's date handling.

A few observations:

  1. The method correctly handles null input by using the nullable DateTime? type.
  2. It uses this to refer to the current DateTime instance, which is correct in this context.

One minor suggestion for improvement:
Consider adding a brief documentation comment to explain the method's purpose and behavior, especially regarding null handling. For example:

/// Returns true if this date is the same day as the given [date].
/// If [date] is null, returns false.
bool isSameDay(DateTime? date) => DateUtils.isSameDay(this, date);

This would enhance the API's clarity for other developers using this extension.

khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.dart (2)

Line range hint 54-58: Excellent addition of the dispose method!

The implementation of the dispose method is a great improvement to the class. It properly cancels the _tournamentSubscription and calls super.dispose(), which helps prevent memory leaks and ensures proper cleanup of resources. This is a best practice when working with subscriptions in Dart and Flutter.


Line range hint 1-73: Overall, this is a well-implemented and focused change.

The addition of the dispose method to the TournamentDetailStateViewNotifier class is a targeted improvement that enhances resource management without affecting the existing functionality. This change follows best practices for handling subscriptions in Dart and Flutter applications.

khelo/lib/domain/formatter/date_formatter.dart (1)

4-4: LGTM: New import added for date extensions.

The addition of style/extensions/date_extensions.dart import is appropriate, likely providing additional date-related utilities for the new functionality.

data/lib/api/tournament/tournament_model.g.dart (3)

Line range hint 1-113: Caution: Generated file modifications

This file is generated code, as indicated by the comment at the top:

// GENERATED CODE - DO NOT MODIFY BY HAND

While the additions for PlayerKeyStatImpl seem to be correctly integrated, it's important to note that manually editing generated files is generally discouraged. Instead, modifications should be made to the source files that generate this code.

To maintain consistency and prevent unintended side effects:

  1. Ensure that the PlayerKeyStat class is properly defined in the source tournament_model.dart file.
  2. Use appropriate annotations (like @JsonSerializable) in the source file to generate the desired serialization methods.
  3. Re-run the code generation tool (likely build_runner) to update this file automatically.

This approach will ensure that the generated code remains consistent with the source definitions and reduces the risk of introducing errors through manual edits.

To confirm the existence of the source file and its annotations, run:

rg "@JsonSerializable" data/lib/api/tournament/tournament_model.dart

This will help verify that the PlayerKeyStat class is properly annotated in the source file.


108-113: LGTM with a minor suggestion for robustness

The _$$PlayerKeyStatImplToJson method looks good and follows the standard pattern for JSON serialization in Dart.

For added robustness, consider handling potential null values, even if they're not expected:

Map<String, dynamic> _$$PlayerKeyStatImplToJson(_$PlayerKeyStatImpl instance) =>
    <String, dynamic>{
      'teamName': instance.teamName ?? '',
      'player': instance.player?.toJson() ?? {},
      'runs': instance.runs ?? 0,
    };

This change ensures that the serialization won't throw errors even if some fields are unexpectedly null.

To ensure that the UserModel class has the necessary toJson method, run the following command:

rg "class UserModel" -A 20

This will help verify the existence of the toJson method in the UserModel class.


101-106: ⚠️ Potential issue

Consider adding null checks and handling potential data loss

The _$$PlayerKeyStatImplFromJson method looks good overall, but there are a couple of points to consider:

  1. The method doesn't perform null checks on the required fields ('teamName', 'player', 'runs'). This could lead to runtime errors if the JSON is malformed or missing these fields.

  2. The 'runs' field is converted from num to int using toInt(). This might cause data loss if the original value is a floating-point number.

Consider the following improvements:

  1. Add null checks for required fields:
_$PlayerKeyStatImpl _$$PlayerKeyStatImplFromJson(Map<String, dynamic> json) =>
    _$PlayerKeyStatImpl(
      teamName: json['teamName'] as String? ?? '',
      player: json['player'] != null
          ? UserModel.fromJson(json['player'] as Map<String, dynamic>)
          : UserModel.empty(), // Assuming there's an empty constructor or a default user
      runs: json['runs'] != null ? (json['runs'] as num).toInt() : 0,
    );
  1. If fractional runs are meaningful in your application, consider keeping 'runs' as a num instead of converting to int, or use round() instead of toInt() to handle floating-point values more accurately.

To ensure that the UserModel class exists and has the necessary fromJson method, run the following command:

This will help verify the existence and structure of the UserModel class.

khelo/lib/ui/flow/tournament/tournament_list_screen.dart (1)

206-211: ⚠️ Potential issue

Caution: Potential null safety issue in date formatting

The removal of the null check for tournament.end_date and the use of the null assertion operator (!) could lead to runtime errors if end_date is ever null. While this change simplifies the code, it assumes that end_date is always non-null, which may not be guaranteed.

Consider using a null-safe approach to maintain robustness:

Text.rich(TextSpan(
  text: DateFormatter.formatDateRange(
    context,
    startDate: tournament.start_date,
    endDate: tournament.end_date ?? tournament.start_date,
    formatType: DateFormatType.dayMonth,
  ),
  // ... rest of the code
))

This approach uses the null-coalescing operator (??) to provide a fallback value if end_date is null, preventing potential runtime errors while maintaining the simplified structure.

To ensure this change is safe, we should verify that end_date is always non-null in the TournamentModel. Run the following script to check for any nullable end_date declarations or usages:

If these searches return results, it indicates that end_date can be null, and we should maintain null-safety in this method.

✅ Verification successful

Null safety for end_date confirmed

The end_date field in TournamentModel is non-nullable. The removal of the null check and the use of the null assertion operator (!) in DateFormatter.formatDateRange are safe and won't lead to runtime errors.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for TournamentModel definition and check end_date nullability
ast-grep --lang dart --pattern 'class TournamentModel {
  $$$
  DateTime? end_date;
  $$$
}'

# Search for any nullable usages of end_date in the codebase
rg --type dart 'tournament\.end_date\?'

Length of output: 136

khelo/lib/ui/flow/tournament/detail/tournament_detail_screen.dart (3)

11-11: LGTM: New import for TournamentDetailOverviewTab

The addition of this import aligns with the PR objective of implementing a tournament overview tab. It's a good practice to keep related components in separate files for better code organization.


100-100: Please clarify the reason for increasing the header size

The size of the SliverPersistentHeader has been increased from 60 to 70. While this change might be necessary to accommodate the new tab or improve the layout, it's not immediately clear why this adjustment was made. Could you please provide some context for this change?

To ensure this change doesn't negatively impact the UI, please verify:

  1. The tab selection area is fully visible and not cut off.
  2. The increased size doesn't push important content too far down the screen.
  3. The change is consistent across different device sizes.

Line range hint 124-137: Address incomplete tab implementation

While the overview tab has been successfully added, I noticed that the UI still shows options for other tabs (Teams, Matches, Points Table, Stats) that haven't been implemented yet. This could lead to a confusing user experience if users can select these tabs but see no content.

Suggestions:

  1. If these tabs are planned for future implementation, consider adding placeholder widgets or "Coming Soon" messages for now.
  2. Alternatively, if these tabs are out of scope for this PR, consider removing them from the UI temporarily.
  3. Update the _tabSelection method to only show the implemented tabs.

Please clarify the intended approach for handling these additional tabs.

To ensure a good user experience, please verify:

  1. The behavior when selecting unimplemented tabs.
  2. The visual consistency across all tab states (selected, unselected, implemented, unimplemented).
khelo/assets/locales/app_en.arb (8)

62-62: LGTM: Improved reusability of "View all" string

The change from "home_screen_view_all_btn" to "common_view_all" improves the reusability of this string across the app. This aligns well with localization best practices.


186-186: LGTM: Clear and consistent tournament info title

The new entry "tournament_detail_overview_info_title" is well-named and follows the established convention for tournament detail strings. The value is properly capitalized and consistent with other title entries.


187-187: LGTM: Concise and clear tournament type title

The new entry "tournament_detail_overview_type_title" is appropriately named and follows the established convention. The value "Type" is concise and clear, maintaining consistency with other title entries.


188-188: LGTM: Clear tournament duration title

The new entry "tournament_detail_overview_duration_title" is well-named and consistent with the established convention. The value "Duration" is clear and appropriate for displaying tournament length information.


190-190: LGTM: Clear and consistent key stats title

The new entry "tournament_detail_overview_key_stats_title" is well-named and follows the established convention. The value "Key Stats" is clear, properly capitalized, and consistent with other title entries.


191-191: LGTM: Clear and consistent most runs title

The new entry "tournament_detail_overview_key_stats_most_runs_title" is appropriately named and follows the established convention. The value "Most Runs" is clear, properly capitalized, and consistent with other title entries.


192-192: LGTM: Clear and consistent featured matches title

The new entry "tournament_detail_overview_featured_matches_title" is well-named and follows the established convention. The value "Featured Matches" is clear, properly capitalized, and consistent with other title entries.


Line range hint 62-193: Overall: Good additions for tournament overview, with one minor issue

The new entries for the tournament overview feature are generally well-structured and consistent. They follow the established naming conventions and provide clear, properly capitalized values. The change from a specific "home_screen_view_all_btn" to a more generic "common_view_all" improves reusability.

However, there is one grammatical issue in the "teams squads" entry that should be addressed.

To ensure these new localization strings are being used correctly in the implementation, please run the following script:

This script will help verify that all new localization keys are being used in the codebase and that the old "home_screen_view_all_btn" key has been fully replaced.

khelo/lib/components/won_by_message_text.dart (1)

12-18: LGTM: Addition of 'isTournament' Property

The addition of the isTournament boolean property with a default value of false allows the widget to conditionally render content based on the tournament status while maintaining backward compatibility.

data/lib/api/tournament/tournament_model.dart (3)

37-39: Confirm exclusion of keyStats from JSON serialization

The keyStats field is annotated with @JsonKey(includeFromJson: false, includeToJson: false), which means it will not be included during JSON serialization or deserialization. If keyStats needs to be stored in or retrieved from Firestore or any JSON operations, consider removing these annotations. Ensure that this exclusion is intentional and aligns with your data handling requirements.


58-59: Verify inclusion of user field in JSON serialization is intended

The @JsonKey(includeToJson: false, includeFromJson: false) annotation has been removed from the user field in TournamentMember. This change means the user field will now be included during JSON serialization and deserialization. Confirm that this inclusion is intentional and that it won't introduce issues such as data redundancy or circular references in your JSON data.


93-101: PlayerKeyStat class is correctly defined

The new PlayerKeyStat class is properly defined with the necessary fields and annotations. The use of @freezed and @JsonSerializable(explicitToJson: true) ensures immutable data models and correct JSON serialization.

data/lib/service/tournament/tournament_service.dart (3)

19-19: BallScoreService provider correctly injected

The BallScoreService is properly injected into the TournamentService provider, ensuring that the service is available for use within the TournamentService.


28-28: BallScoreService dependency added to TournamentService

Adding _ballScoreService as a final field and including it in the constructor parameters aligns with the existing dependency injection pattern. This ensures that BallScoreService is accessible throughout the TournamentService.

Also applies to: 35-35


100-102: Key statistics integrated into tournament data

The inclusion of keyStats in the tournament object by calling getKeyStats(matches) enhances the tournament data with valuable player statistics. This is correctly implemented and will improve the functionality of the streamTournamentById method.

data/lib/api/tournament/tournament_model.freezed.dart (6)

321-329: Initialization of '_keyStats' field is correct

The private field _keyStats is properly initialized in the constructor, and the corresponding public getter keyStats provides read-only access. This ensures that the TournamentModel remains immutable.


400-408: Ensured immutability of 'keyStats' list

Wrapping _keyStats with EqualUnmodifiableListView in the getter ensures that the returned list cannot be modified, preserving the immutability of the TournamentModel instance.


77-79: Update 'copyWith' method usage to include 'keyStats'

The copyWith method now includes the keyStats parameter. Ensure that all calls to copyWith on TournamentModel are updated to handle keyStats appropriately to prevent any unexpected behavior.

You can verify all usages of copyWith on TournamentModel in the codebase with the following script:

#!/bin/bash
# Description: Find all usages of 'TournamentModel.copyWith' and check for 'keyStats' parameter.

# Test: Search for 'copyWith' method calls on 'TournamentModel'.
rg --type dart 'TournamentModel' -A 5 | rg '\.copyWith\(' -C 3

170-173: Ensure correct null handling for 'keyStats' in 'copyWith'

In the copyWith implementation, keyStats is nullable. Verify that this nullability aligns with how keyStats is used elsewhere and that it doesn't introduce any null-safety issues.

To check for potential nullability issues, run:

#!/bin/bash
# Description: Search for usages of 'keyStats' where null handling is critical.

# Test: Find places where 'keyStats' is accessed and ensure null checks are in place.
rg --type dart 'keyStats' -A 5 | rg -v '@JsonKey' -B 2

764-944: ⚠️ Potential issue

Add JSON serialization for 'PlayerKeyStat' class

The PlayerKeyStat class is defined with properties teamName, player, and runs. However, it lacks JSON serialization annotations. If instances of PlayerKeyStat need to be serialized or deserialized, consider adding @JsonSerializable and implementing toJson and fromJson methods.

To verify if PlayerKeyStat has the necessary JSON serialization methods, run:

#!/bin/bash
# Description: Check for JSON serialization annotations and methods in 'PlayerKeyStat'.

# Test: Search for '@JsonSerializable' annotation on 'PlayerKeyStat' class.
rg --type dart '@JsonSerializable' -A 3 | rg 'class PlayerKeyStat'

# Check for 'toJson' and 'fromJson' methods in 'PlayerKeyStat'.
rg --type dart 'class PlayerKeyStat' -A 20 | rg 'toJson|fromJson'

42-43: ⚠️ Potential issue

Ensure 'keyStats' field is serialized if needed

The keyStats field is annotated with @JsonKey(includeFromJson: false, includeToJson: false), meaning it will not be included during JSON serialization or deserialization. If keyStats needs to be persisted or transmitted (e.g., via APIs), consider removing these annotations to include it in JSON operations.

To verify where keyStats is being used and ensure it aligns with your serialization logic, run the following script:

@canopas canopas deleted a comment from coderabbitai bot Oct 18, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 18, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 18, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 18, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 18, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 18, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 18, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 18, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 18, 2024
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Outside diff range and nitpick comments (5)
data/lib/service/tournament/tournament_service.dart (1)

123-146: LGTM: getKeyStats method implemented correctly with room for optimization.

The getKeyStats method is well-implemented and aligns with the requirements. It efficiently retrieves ball scores and calculates player statistics. The use of extension methods enhances maintainability.

However, for large datasets, the nested loops might become a performance bottleneck. Consider refactoring to use more efficient data structures or parallel processing for better performance with large tournaments.

Here's a potential optimization using a more efficient data structure:

Future<List<PlayerKeyStat>> getKeyStats(List<MatchModel> matches) async {
  final matchIds = matches.map((match) => match.id).toList();
  final scores = await _ballScoreService.getBallScoresByMatchIds(matchIds);

  final Map<String, PlayerKeyStat> playerStatsMap = {};

  for (final match in matches) {
    for (final team in match.teams) {
      for (final player in team.squad) {
        final stats = scores.calculateUserStats(player.id);
        playerStatsMap[player.id] = PlayerKeyStat(
          player: player.player,
          teamName: team.team.name,
          stats: stats,
        );
      }
    }
  }

  return playerStatsMap.values.toList().getTopKeyStats()
    ..sort((a, b) => b.value?.compareTo(a.value ?? 0) ?? 0);
}

This optimization uses a Map to store player stats, potentially reducing the time complexity for large datasets.

khelo/lib/domain/extensions/enum_extensions.dart (1)

318-331: LGTM! Consider a minor improvement for consistency.

The new TournamentKeyStatString extension is well-implemented and follows the established pattern in the file. It provides localization support for tournament key statistics, which aligns with the PR objectives.

For consistency with other extensions in this file, consider adding a blank line before the extension definition:

+
 extension TournamentKeyStatString on KeyStatTag {
   String getString(BuildContext context) {
     // ... (rest of the code remains unchanged)
   }
 }
data/lib/api/tournament/tournament_model.freezed.dart (1)

42-43: LGTM! Consider adding a comment explaining the keyStats property.

The addition of the keyStats property to the TournamentModel class is well-implemented. The @JsonKey annotation correctly excludes it from JSON serialization, which is appropriate if this data is computed or fetched separately.

Consider adding a brief comment explaining the purpose of the keyStats property and why it's excluded from JSON serialization. This would improve code readability and maintainability.

Also applies to: 77-79, 170-173, 293-296, 321-323, 400-407

data/lib/api/ball_score/ball_score_model.dart (2)

Line range hint 718-722: Fix logical error in calculating wicketTaken in calculateBowlingStats

The current logic counts wickets when the dismissal types are retired, retiredHurt, or timedOut, which are not credited to the bowler. To accurately calculate the number of wickets taken by the bowler, these dismissal types should be excluded from the count.

Apply this diff to correct the condition:

 final wicketTaken = deliveries
     .where(
       (element) =>
           element.wicket_type != null &&
-          (element.wicket_type == WicketType.retired ||
-               element.wicket_type == WicketType.retiredHurt ||
-               element.wicket_type == WicketType.timedOut),
+          element.wicket_type != WicketType.retired &&
+          element.wicket_type != WicketType.retiredHurt &&
+          element.wicket_type != WicketType.timedOut,
     )
     .length;

Line range hint 656-659: Correct the logic for calculating ducks in calculateBattingStats

The current logic counts ducks when a player is dismissed after facing between 0 and 2 balls. However, a duck is officially recorded when a player is dismissed without scoring any runs, regardless of balls faced. The condition should check if the player was dismissed and scored zero runs in the innings.

Apply this diff to fix the logic:

 if (isDismissed && inningRunScored == 0) {
     ducks++;
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between d5935e3 and 51e2e73.

📒 Files selected for processing (16)
  • data/lib/api/ball_score/ball_score_model.dart (4 hunks)
  • data/lib/api/ball_score/ball_score_model.freezed.dart (24 hunks)
  • data/lib/api/ball_score/ball_score_model.g.dart (1 hunks)
  • data/lib/api/tournament/tournament_model.dart (4 hunks)
  • data/lib/api/tournament/tournament_model.freezed.dart (14 hunks)
  • data/lib/api/tournament/tournament_model.g.dart (1 hunks)
  • data/lib/service/match/match_service.dart (3 hunks)
  • data/lib/service/tournament/tournament_service.dart (5 hunks)
  • khelo/assets/locales/app_en.arb (4 hunks)
  • khelo/lib/components/won_by_message_text.dart (2 hunks)
  • khelo/lib/domain/extensions/enum_extensions.dart (1 hunks)
  • khelo/lib/domain/formatter/date_formatter.dart (2 hunks)
  • khelo/lib/ui/flow/home/home_screen.dart (1 hunks)
  • khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_overview_tab.dart (1 hunks)
  • khelo/lib/ui/flow/tournament/detail/tournament_detail_screen.dart (4 hunks)
  • khelo/lib/ui/flow/tournament/tournament_list_screen.dart (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • khelo/assets/locales/app_en.arb
  • khelo/lib/components/won_by_message_text.dart
  • khelo/lib/domain/formatter/date_formatter.dart
  • khelo/lib/ui/flow/home/home_screen.dart
  • khelo/lib/ui/flow/tournament/tournament_list_screen.dart
🧰 Additional context used
🔇 Additional comments (38)
data/lib/api/tournament/tournament_model.g.dart (4)

101-108: LGTM: Correct implementation of JSON deserialization for PlayerKeyStat

The _$$PlayerKeyStatImplFromJson function correctly deserializes JSON data into a PlayerKeyStat object, handling nested objects and optional fields appropriately.


110-117: LGTM: Correct implementation of JSON serialization for PlayerKeyStat

The _$$PlayerKeyStatImplToJson function properly serializes a PlayerKeyStat object to JSON, correctly handling nested objects and enum values.


Line range hint 1-124: Overall, the generated code looks good and consistent

The additions for PlayerKeyStat in this generated file are consistent with the existing code structure and follow proper serialization practices. Remember that this is an auto-generated file and should not be manually modified. Any changes should be made in the source file (tournament_model.dart) instead.


119-124: LGTM: KeyStatTagEnumMap is correctly defined

The _$KeyStatTagEnumMap constant correctly maps KeyStatTag enum values to their string representations.

Consider if this list of key stats is exhaustive or if there might be plans to add more in the future. If additional stats are likely, ensure that the KeyStatTag enum in the source file (tournament_model.dart) is easily extensible.

To verify the completeness of the KeyStatTag enum, run the following script:

This will help identify any planned additions to the KeyStatTag enum that might not be reflected in this generated code yet.

data/lib/service/tournament/tournament_service.dart (4)

4-5: LGTM: New imports are appropriate for the added functionality.

The new imports for ball score models and services are correctly added and align with the new features being implemented in this file.

Also applies to: 9-9


20-20: LGTM: New dependency correctly added to the provider.

The ballScoreServiceProvider is appropriately included in the tournamentServiceProvider, which is consistent with the new functionality being implemented.


29-29: LGTM: TournamentService class correctly updated with new dependency.

The BallScoreService field and constructor parameter are appropriately added to the TournamentService class, maintaining consistency with the provider changes.

Also applies to: 36-36


101-103: LGTM: streamTournamentById method updated to include key stats.

The method now correctly retrieves and includes key stats in the tournament model, which aligns with the new functionality being implemented.

data/lib/service/match/match_service.dart (3)

535-553: Great job on optimizing the getTeamsList method!

The refactoring to use Future.wait for parallel execution of team data fetching and player list retrieval is an excellent performance improvement. This change reduces the overall execution time by running these operations concurrently instead of sequentially.


Line range hint 570-580: Nice improvement to the getPlayerListFromPlayerIds method!

The refactoring to use a more functional approach with map has made the code more concise and easier to read. The method now efficiently creates MatchPlayer objects while preserving the performance data from the original objects.


587-597: Excellent improvement to the getMatchesByIds method!

The implementation now uses a batch retrieval method with whereIn, which addresses the performance issue raised in the previous review. The use of Future.wait for processing the retrieved matches is also efficient.

However, note that the added limit of 10 matches might cause some matches to be omitted if more than 10 matchIds are provided. Consider implementing a pagination mechanism or increasing the limit if larger batches are expected.

To verify the impact of the 10-match limit, you can run the following script:

data/lib/api/tournament/tournament_model.freezed.dart (2)

764-1006: LGTM! Well-structured PlayerKeyStat class.

The new PlayerKeyStat class is well-implemented using the Freezed package. It provides a clear structure for representing key player statistics in a tournament, with appropriate properties and generated methods for immutability and convenience.

The class design looks good and should integrate well with the TournamentModel.


Line range hint 1-1006: Verify the integration of PlayerKeyStat with existing tournament logic.

The addition of the PlayerKeyStat class and its integration with TournamentModel enhances the ability to track player performance within tournaments. This is a valuable feature that aligns well with the PR objectives of implementing a tournament overview tab.

To ensure smooth integration, please verify:

  1. The computation or fetching mechanism for keyStats.
  2. Any UI components that will display this new data.
  3. Performance impact of adding this potentially large list to the TournamentModel.

Run the following script to check for potential usage and integration points:

This will help ensure that the new PlayerKeyStat is properly integrated and utilized in the codebase.

✅ Verification successful

PlayerKeyStat integration is properly implemented and utilized within tournament logic.

  • Verified usage in tournament_service.dart and tournament_detail_overview_tab.dart.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for PlayerKeyStat usage and potential integration points

# Search for PlayerKeyStat usage
echo "PlayerKeyStat usage:"
rg "PlayerKeyStat" --type dart

# Search for keyStats access in TournamentModel
echo "\nkeyStats access in TournamentModel:"
rg "tournament.*keyStats" --type dart

# Search for potential UI components that might use this data
echo "\nPotential UI components using tournament statistics:"
rg "tournament.*stat" --type dart | grep -i "widget\|build\|display"

Length of output: 7093


Script:

#!/bin/bash
# Description: Search for usage of 'keyStats' in UI components with broader patterns

# Search for 'keyStats' in all Dart UI files with broader context
echo "Searching for 'keyStats' usage in UI components with broader patterns:"
rg "keyStats" --type dart | grep -iE "widget|build|display|view|screen|page|component"

# Find UI components that receive 'keyStats' as parameters
echo "\nSearching for UI components that accept 'keyStats' as parameters:"
rg "Widget\s+\w+\s*\([^)]*keyStats" --type dart

Length of output: 1773

data/lib/api/tournament/tournament_model.dart (5)

7-7: Import Statement Approved

The import of ball_score_model.dart is necessary for accessing UserStat and related models.


38-40: Verify Exclusion of keyStats from JSON Serialization

The keyStats field is annotated with @JsonKey(includeFromJson: false, includeToJson: false), which means it will be excluded from JSON serialization and deserialization. Is this intentional? If keyStats needs to be persisted or transmitted over the network, consider removing these annotations to include it in the JSON data.


59-60: Including user Field in JSON Serialization

The user field in TournamentMember no longer has the @JsonKey(includeToJson: false, includeFromJson: false) annotation. This change means the user object will now be serialized and deserialized to/from JSON. Ensure this is intended, and consider the impact on data payload size and any potential exposure of sensitive user information.


94-105: Approval of PlayerKeyStat Class Definition

The PlayerKeyStat class is well-defined with the required fields and appropriate JSON serialization annotations. This addition enhances the model to include player statistics effectively.


106-112: Approval of KeyStatTag Enum Definition

The KeyStatTag enum is properly defined, providing clear identifiers for different statistic categories.

khelo/lib/ui/flow/tournament/detail/tournament_detail_screen.dart (2)

85-106: Implementation of NestedScrollView with SliverAppBar looks good

The use of NestedScrollView along with SliverAppBar and SliverPersistentHeader effectively manages the scrollable content with a collapsible header. This enhances the user experience by keeping the header visible while scrolling.


113-115: User cannot swipe between pages due to disabled scroll physics

Setting physics: const NeverScrollableScrollPhysics() on the PageView disables user swiping between pages. If the intention is to prevent swipe gestures and control page navigation solely through the tab buttons, this is acceptable. Otherwise, enabling swipe gestures could improve usability.

Please confirm whether disabling swipe navigation is intentional. If not, consider removing NeverScrollableScrollPhysics to allow users to navigate between pages with swipe gestures.

data/lib/api/ball_score/ball_score_model.g.dart (4)

111-129: LGTM!

The JSON serialization methods for UserStatImpl are correctly implemented.


131-158: Confirm default values for missing or null JSON fields in BattingStatImpl

In the _$BattingStatImplFromJson method, numerical fields default to 0 or 0.0 when the JSON fields are missing or null. Please verify that defaulting to zero is acceptable for fields like innings, runScored, average, etc. If these fields should not silently default to zero, consider handling missing data differently to avoid masking potential data issues.


159-186: Confirm default values for missing or null JSON fields in BowlingStatImpl

In the _$BowlingStatImplFromJson method, numerical fields default to 0 or 0.0 when the JSON fields are missing or null. Please verify that defaulting to zero is appropriate for fields like innings, wicketTaken, economyRate, etc. If zero is not a meaningful default, consider implementing error handling for missing data.


187-200: Confirm default values for missing or null JSON fields in FieldingStatImpl

In the _$FieldingStatImplFromJson method, fields like catches, runOut, and stumping default to 0 when the JSON fields are missing or null. Please ensure that defaulting to zero is acceptable for these statistics, and that it won't obscure any data inconsistencies.

data/lib/api/ball_score/ball_score_model.dart (4)

145-146: Well-implemented fromJson constructor in UserStat class

The addition of the fromJson factory constructor enhances the class's ability to serialize and deserialize JSON data efficiently.


164-165: Well-implemented fromJson constructor in BattingStat class

Including the fromJson method ensures seamless JSON serialization and deserialization for the BattingStat class.


183-184: Well-implemented fromJson constructor in BowlingStat class

The fromJson factory constructor addition facilitates efficient JSON data handling for the BowlingStat class.


195-196: Well-implemented fromJson constructor in FieldingStat class

Adding the fromJson method enhances JSON serialization and deserialization capabilities for the FieldingStat class.

data/lib/api/ball_score/ball_score_model.freezed.dart (10)

572-574: UserStat JSON deserialization is correctly implemented.

The _$UserStatFromJson function properly delegates to _UserStat.fromJson(json), ensuring accurate deserialization.


741-747: UserStat class implementation is correct with JSON serialization support.

The _$UserStatImpl class correctly includes the @JsonSerializable() annotation. The fromJson factory constructor and toJson method are properly implemented for JSON serialization and deserialization.


818-821: BattingStat JSON deserialization is correctly implemented.

The _$BattingStatFromJson function correctly delegates to _BattingStat.fromJson(json).


1040-1042: BattingStat class implementation is correct with default values.

The _$BattingStatImpl class includes appropriate default values for all fields and correctly defines the fromJson factory constructor.


1166-1169: BowlingStat JSON deserialization is correctly implemented.

The _$BowlingStatFromJson function properly delegates to _BowlingStat.fromJson(json).


1388-1390: BowlingStat class implementation is correct with default values.

The _$BowlingStatImpl class includes appropriate default values for all fields and correctly defines the fromJson factory constructor.


1525-1528: FieldingStat JSON deserialization is correctly implemented.

The _$FieldingStatFromJson function properly delegates to _FieldingStat.fromJson(json).


1636-1643: FieldingStat class implementation is correct with default values.

The _$FieldingStatImpl class includes appropriate default values and correctly defines the fromJson factory constructor and toJson method.


1682-1687: FieldingStat toJson method is correctly implemented.

The toJson method properly serializes the FieldingStat instance to a JSON map.


Line range hint 1830-1835: All new data classes are correctly defined with serialization support.

Classes like OverStatModel, TeamRunStat, OverSummary, BatsmanSummary, BowlerSummary, Player, and ExtraSummary are correctly implemented with necessary constructors, default values, and serialization methods.

@canopas canopas deleted a comment from coderabbitai bot Oct 21, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 21, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 21, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 21, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 21, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 21, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 21, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 21, 2024
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Outside diff range and nitpick comments (7)
data/lib/api/tournament/tournament_model.g.dart (2)

100-116: LGTM! Consider adding null checks for nested objects.

The new JSON serialization and deserialization functions for PlayerKeyStat look good. They correctly handle nested objects and the optional tag field.

Consider adding null checks for the nested objects to improve robustness:

 _$PlayerKeyStatImpl _$$PlayerKeyStatImplFromJson(Map<String, dynamic> json) =>
     _$PlayerKeyStatImpl(
       teamName: json['teamName'] as String,
-      player: UserModel.fromJson(json['player'] as Map<String, dynamic>),
-      stats: UserStat.fromJson(json['stats'] as Map<String, dynamic>),
+      player: json['player'] == null ? null : UserModel.fromJson(json['player'] as Map<String, dynamic>),
+      stats: json['stats'] == null ? null : UserStat.fromJson(json['stats'] as Map<String, dynamic>),
       tag: $enumDecodeNullable(_$KeyStatTagEnumMap, json['tag']),
       value: (json['value'] as num?)?.toInt(),
     );

118-123: LGTM! Consider future expansions for comprehensive stats.

The _$KeyStatTagEnumMap constant correctly maps the KeyStatTag enum values. It covers basic cricket statistics, which is appropriate for a tournament app.

As the app evolves, consider expanding this enum to include more comprehensive statistics such as:

  • Best batting average
  • Best bowling average
  • Highest strike rate
  • Best economy rate

This will allow for more detailed player performance tracking in tournaments.

data/lib/service/tournament/tournament_service.dart (2)

88-88: LGTM: Default end_date set appropriately.

Setting the default end_date to one day after the current date is a good practice. It ensures that new tournaments always have an end date.

Consider extracting this default duration to a constant for better maintainability:

const defaultTournamentDuration = Duration(days: 1);
// ...
end_date: DateTime.now().add(defaultTournamentDuration),

124-147: Acknowledge correction of KeyStats implementation.

The implementation of getKeyStats now correctly addresses the previous misunderstanding. It calculates stats for all players in the tournament, not just the highest run scorer.

To improve clarity, consider adding a comment explaining the purpose of the method:

/// Calculates key statistics for all players in the tournament,
/// including runs, wickets, and other relevant metrics.
Future<List<PlayerKeyStat>> getKeyStats(List<MatchModel> matches) async {
  // ... (rest of the method)
}

This comment will help future developers understand the intent of the method at a glance.

data/lib/api/tournament/tournament_model.freezed.dart (1)

764-1006: LGTM: PlayerKeyStat class added successfully.

The new PlayerKeyStat class is a well-structured addition that supports the tracking of individual player statistics within a tournament. Its implementation using the freezed package ensures consistency with other model classes.

Consider adding a brief class-level documentation comment to explain the purpose and usage of this class.

khelo/lib/ui/flow/tournament/detail/tournament_detail_screen.dart (2)

171-172: Allow text scaling for improved accessibility

The text uses textScaler: TextScaler.noScaling, which prevents it from scaling according to user accessibility settings. This may hinder users who rely on larger font sizes for readability.

Consider removing textScaler: TextScaler.noScaling to support dynamic text scaling:

 Text(
   tournament.name,
   style: AppTextStyle.header2.copyWith(
     color: context.colorScheme.textPrimary,
   ),
   overflow: TextOverflow.ellipsis,
-  textScaler: TextScaler.noScaling,
 ),

241-242: Allow text scaling for improved accessibility

Again, textScaler: TextScaler.noScaling is used here, preventing text from adapting to user-preferred font sizes. Supporting text scaling enhances accessibility for all users.

Consider removing textScaler: TextScaler.noScaling:

 Text(
   tournament.name,
   style: AppTextStyle.header1.copyWith(
     color: tournament.banner_img_url != null
         ? Colors.white
         : context.colorScheme.textPrimary,
   ),
   overflow: TextOverflow.ellipsis,
-  textScaler: TextScaler.noScaling,
   maxLines: 2,
 ),
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 33745ac and 9fc95f0.

📒 Files selected for processing (7)
  • data/lib/api/tournament/tournament_model.dart (5 hunks)
  • data/lib/api/tournament/tournament_model.freezed.dart (18 hunks)
  • data/lib/api/tournament/tournament_model.g.dart (3 hunks)
  • data/lib/service/tournament/tournament_service.dart (6 hunks)
  • khelo/lib/domain/formatter/date_formatter.dart (2 hunks)
  • khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_overview_tab.dart (1 hunks)
  • khelo/lib/ui/flow/tournament/detail/tournament_detail_screen.dart (8 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • khelo/lib/domain/formatter/date_formatter.dart
  • khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_overview_tab.dart
🧰 Additional context used
🔇 Additional comments (9)
data/lib/api/tournament/tournament_model.g.dart (2)

51-51: LGTM! Consistent with the fromJson changes.

The change to always include end_date in the JSON output is consistent with making it a required field in the model. This ensures that the end date is always serialized when converting a TournamentModel to JSON.


26-27: LGTM! Verify impact on existing data.

The change to make end_date a required field and use TimeStampJsonConverter is good. It ensures consistency and data integrity for tournaments.

Please run the following script to check if this change affects any existing tournament data:

✅ Verification successful

Verified: All TournamentModel.fromJson calls correctly handle the end_date field.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for tournaments without end_date
# Expect: No output if all tournaments have end_date

rg -g '*.dart' -g '!*.g.dart' 'TournamentModel.fromJson' | xargs -I {} rg -A 10 'end_date' {}

Length of output: 677


Script:

#!/bin/bash
# Description: Locate all Dart files related to TournamentModel to verify their existence and correct paths

fd 'tournament_model.*\.dart$' . 

Length of output: 188


Script:

#!/bin/bash
# Description: Verify that all TournamentModel.fromJson calls include 'end_date'
# Expect: Lines containing 'TournamentModel.fromJson' followed by 'end_date' handling

# List of relevant files
files=(
  "./data/lib/api/tournament/tournament_model.dart"
  "./data/lib/api/tournament/tournament_model.freezed.dart"
  "./data/lib/api/tournament/tournament_model.g.dart"
)

# Iterate through each file and check for 'TournamentModel.fromJson' and 'end_date'
for file in "${files[@]}"; do
  if [[ -f "$file" ]]; then
    echo "Checking $file..."
    rg 'TournamentModel\.fromJson' "$file" -A 5 | rg 'end_date'
  else
    echo "File not found: $file"
  fi
done

Length of output: 1157

data/lib/service/tournament/tournament_service.dart (2)

4-5: LGTM: New imports and dependencies added correctly.

The new imports and the BallScoreService dependency are appropriately added to support the new functionality for retrieving key stats.

Also applies to: 9-9, 20-20, 29-36


102-104: LGTM: Key stats integration in streamTournamentById.

The getKeyStats method is correctly integrated into the streamTournamentById method. The tournament model is appropriately updated with both matches and key stats.

data/lib/api/tournament/tournament_model.freezed.dart (5)

35-35: LGTM: Addition of keyStats enhances the tournament model.

The new keyStats property adds support for player statistics in the tournament model, which aligns well with the PR objective of implementing a tournament overview tab. The @JsonKey annotation correctly excludes this derived data from JSON operations.

Also applies to: 42-43


170-173: LGTM: copyWith method correctly updated.

The copyWith method has been properly updated to include the new keyStats property. This change ensures that modified copies of TournamentModel instances can be created with the new player statistics data.


315-315: LGTM: Constructor updated correctly.

The TournamentModel constructor has been properly updated to include the new keyStats property with a sensible default empty list. The end_date parameter is now correctly marked as required, aligning with its non-nullable status.

Also applies to: 321-323


411-411: LGTM: Object representation methods updated correctly.

The toString, == operator, and hashCode methods have been properly updated to include the new keyStats property. This ensures consistent and correct behavior when comparing or representing TournamentModel instances.

Also applies to: 439-440, 460-461


35-35: Verify impact of end_date nullability change.

The end_date property has been changed from nullable (DateTime?) to non-nullable (DateTime). This is a breaking change that may affect existing code relying on the nullability of this field.

Please run the following script to identify potential issues:

✅ Verification successful

End_date nullability change verified: No impacts detected.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find usages of TournamentModel where end_date is checked for null or assigned null

# Search for null checks on end_date
echo "Checking for null checks on end_date:"
rg "tournament.*end_date\s*[!=]=\s*null" -g '!*.freezed.dart'

# Search for null assignments to end_date
echo "Checking for null assignments to end_date:"
rg "tournament.*end_date\s*=\s*null" -g '!*.freezed.dart'

Length of output: 303


Script:

#!/bin/bash
# Description: Enhanced search for usages of TournamentModel where end_date is checked for null or assigned null.

# Search for null checks on end_date with varied patterns
echo "Checking for null checks on end_date (expanded patterns):"
rg "\.end_date\s*!=\s*null" -g '!*.freezed.dart'
rg "\.end_date\s*!==\s*null" -g '!*.freezed.dart'
rg "if\s*\(\s*.*\.end_date\s*==\s*null\s*\)" -g '!*.freezed.dart'
rg "if\s*\(\s*.*\.end_date\s*!=\s*null\s*\)" -g '!*.freezed.dart'

# Search for null assignments to end_date with varied patterns
echo "Checking for null assignments to end_date (expanded patterns):"
rg "\.end_date\s*=\s*null" -g '!*.freezed.dart'
rg "set\s*\(\s*.*\.end_date\s*,\s*null\s*\)" -g '!*.freezed.dart'

# Search for any assignments to end_date regardless of assigned value
echo "Checking for any assignments to end_date:"
rg "\.end_date\s*=" -g '!*.freezed.dart'

Length of output: 752

@canopas canopas deleted a comment from coderabbitai bot Oct 23, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 23, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 23, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 23, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 23, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 23, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 23, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 23, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 23, 2024
@canopas canopas deleted a comment from coderabbitai bot Oct 23, 2024
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (2)
data/lib/service/match/match_service.dart (2)

535-553: Add validation and null checks for robustness.

The parallel fetching implementation is efficient, but could benefit from additional error handling.

Consider these improvements:

 Future<List<MatchTeamModel>> getTeamsList(List<MatchTeamModel> teamList) async {
   try {
+    if (teamList.isEmpty) return [];
     final teamIds = teamList.map((e) => e.team_id).toList();
     final playerIds = teamList.expand((team) => team.squad).toList();

     final teamsData = await Future.wait([
       _teamService.getTeamsByIds(teamIds),
       getPlayerListFromPlayerIds(playerIds),
     ]);

     final List<TeamModel> teams = teamsData[0] as List<TeamModel>;
+    if (teams.length != teamIds.length) {
+      throw AppError('Some teams could not be found');
+    }
     final List<MatchPlayer> players = teamsData[1] as List<MatchPlayer>;

     final List<List<MatchPlayer>> squads = teamList.map((team) {
       return players.where((player) => team.squad.contains(player)).toList();
     }).toList();

     return List.generate(teamList.length, (index) {
       return teamList[index].copyWith(
         team: teams[index],
         squad: squads[index],
       );
     });
   } catch (error, stack) {
     throw AppError.fromError(error, stack);
   }
 }

Line range hint 570-577: Handle potential missing players safely.

The firstWhere operation could throw a StateError if a player is not found.

Apply this safer implementation:

 return users.map((user) {
-  final matchPlayer =
-      players.firstWhere((element) => element.id == user.id);
+  final matchPlayer = players.firstWhere(
+    (element) => element.id == user.id,
+    orElse: () => MatchPlayer(
+      id: user.id,
+      player: user,
+      performance: PlayerPerformance(),
+    ),
+  );

   return MatchPlayer(
     player: user,
     performance: matchPlayer.performance,
     id: user.id,
   );
 }).toList();
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between f1dc02f and 4f76745.

📒 Files selected for processing (1)
  • data/lib/service/match/match_service.dart (3 hunks)
🧰 Additional context used
🔇 Additional comments (1)
data/lib/service/match/match_service.dart (1)

586-603: LGTM! Well-implemented chunking solution.

The implementation correctly addresses the previous review comments by:

  1. Handling empty matchIds list
  2. Chunking IDs into groups of 10 for Firestore's whereIn limitation
  3. Using parallel processing for team data fetching

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants