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

Manage user stats in score board #146

Merged
merged 9 commits into from
Nov 27, 2024
Merged

Manage user stats in score board #146

merged 9 commits into from
Nov 27, 2024

Conversation

cp-mayank
Copy link
Collaborator

@cp-mayank cp-mayank commented Nov 26, 2024

  • Refactor user stats classes and method
  • Store stats in user sub collection
  • Update user stats in inning completion
user-stats.webm

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced user statistics management, allowing for detailed tracking of player performance in batting, bowling, and fielding.
    • Added support for fetching and updating user statistics via the UserService.
    • New user statistics structure consolidates data into a single list for improved clarity.
    • Added a new plugin for shared preferences on Android.
  • Bug Fixes

    • Enhanced error handling in user statistics updates to ensure smoother functionality.
  • Documentation

    • Updated code comments and structure to improve maintainability and clarity regarding user statistics.
  • Refactor

    • Streamlined data access patterns for player statistics across various components, removing unnecessary null checks.
    • Updated naming conventions for statistics fields to use snake_case for consistency.
    • Simplified logic for retrieving user statistics in the UI components.

Copy link

coderabbitai bot commented Nov 26, 2024

Walkthrough

The pull request includes updates to several files, primarily focusing on restructuring user statistics models in a sports context. Key changes involve the removal of outdated classes and the introduction of new classes for batting, bowling, and fielding statistics. Additionally, new methods for calculating and managing user statistics are implemented, along with modifications to the user service for fetching statistics. The changes also include updates to UI components and view models to reflect the new data structures, enhancing the overall management of user performance metrics.

Changes

File Path Change Summary
data/.flutter-plugins-dependencies Updated date_created field and added shared_preferences_android plugin to the Android section.
data/lib/api/ball_score/ball_score_model.dart Removed UserStat, BattingStat, BowlingStat, FieldingStat classes; added Batting, Bowling, Fielding classes; updated calculateUserStats, calculateBattingStats, calculateBowlingStats, and calculateFieldingStats methods.
data/lib/api/ball_score/ball_score_model.freezed.dart Removed user statistics classes and added OverStatModel, TeamRunStat, and OverSummary classes.
data/lib/api/ball_score/ball_score_model.g.dart Removed JSON serialization functions for user statistics classes.
data/lib/api/tournament/tournament_model.dart Updated getTopKeyStats method to access batting and bowling statistics using new data structures.
data/lib/api/user/user_models.dart Added UserStatType enum, UserStat, Batting, Bowling, and Fielding classes with JSON serialization methods.
data/lib/api/user/user_models.freezed.dart Added UserStat, Batting, Bowling, and Fielding classes with properties and methods for JSON serialization.
data/lib/api/user/user_models.g.dart Added JSON serialization methods for UserStatsImpl, BattingImpl, BowlingImpl, and FieldingImpl classes.
data/lib/service/user/user_service.dart Introduced methods for streaming and retrieving user statistics; reintroduced user management methods.
data/lib/utils/constant/firestore_constant.dart Added constants for user statistics collection and type.
khelo/lib/ui/flow/score_board/score_board_view_model.dart Integrated UserService for fetching and updating player statistics; added _addPlayerStats method.
khelo/lib/ui/flow/stats/user_stat/user_stat_screen.dart Updated state management logic to retrieve user statistics more effectively.
khelo/lib/ui/flow/stats/user_stat/user_stat_view_model.dart Refactored to focus on user statistics instead of match statistics; updated state management.
khelo/lib/ui/flow/stats/user_stat/user_stat_view_model.freezed.dart Updated UserStatViewState to consolidate user statistics into a single list.
khelo/lib/ui/flow/team/user_detail/component/user_detail_batting_content.dart Updated batting statistics properties from BattingStat? to Batting?.
khelo/lib/ui/flow/team/user_detail/component/user_detail_bowling_content.dart Updated bowling statistics properties from BowlingStat? to Bowling?.
khelo/lib/ui/flow/team/user_detail/component/user_detail_fielding_content.dart Updated fielding statistics properties from FieldingStat? to Fielding?.
khelo/lib/ui/flow/team/user_detail/user_detail_screen.dart Updated user statistics retrieval logic to use new data structures.
khelo/lib/ui/flow/team/user_detail/user_detail_view_model.dart Refactored to focus on user statistics; removed match-related dependencies.
khelo/lib/ui/flow/team/user_detail/user_detail_view_model.freezed.dart Updated UserDetailViewState to include a list of UserStat objects instead of match statistics.
khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_stats_tab.dart Modified player statistics handling in _dataRow method to remove optional chaining.
khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.dart Updated player statistics access patterns to remove nullable properties and default values.

Possibly related PRs

Suggested reviewers

  • cp-sidhdhi-p

🐇 In the realm of stats, we hop and play,
With batting, bowling, fielding on display.
New classes arise, old ones take flight,
User stats shine, oh what a sight!
From matches to metrics, we gather and cheer,
In this world of sports, our vision is clear! 🏏✨


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.

@cp-mayank cp-mayank changed the title Manage user state in score board Manage user stats in score board Nov 26, 2024
@cp-mayank cp-mayank marked this pull request as ready for review November 26, 2024 10:26
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 (33)
khelo/lib/ui/flow/team/user_detail/component/user_detail_fielding_content.dart (1)

Line range hint 21-62: LGTM! Consider adding documentation for the statsDataRow widget.

The build method implementation is clean and well-structured. It properly handles null values and uses localization consistently.

Consider adding documentation for the statsDataRow widget to explain its parameters and usage, as it seems to be a reusable component.

data/lib/utils/constant/firestore_constant.dart (1)

11-11: Consider using plural form for collection name

For consistency with other collection names (matchesCollection, teamsCollection, usersCollection), consider using plural form:

-  static const String userStatCollection = "user_stat";
+  static const String userStatsCollection = "user_stats";
khelo/lib/ui/flow/team/user_detail/component/user_detail_batting_content.dart (1)

Line range hint 1-5: Remove unused import

The import of user_detail_bowling_content.dart appears to be unused in this file.

 import 'package:data/api/user/user_models.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:khelo/domain/extensions/context_extensions.dart';
-import 'package:khelo/ui/flow/team/user_detail/component/user_detail_bowling_content.dart';
khelo/lib/ui/flow/team/user_detail/component/user_detail_bowling_content.dart (1)

Line range hint 117-170: Consider extracting the statsDataRow to a shared component

The statsDataRow implementation is well-structured, but since it's likely used across different stat views (batting, bowling, fielding), consider extracting it to a shared component for better reusability.

+ // TODO: Move to a shared component like 'components/stats_data_row.dart'
Widget statsDataRow(...)
khelo/lib/ui/flow/stats/user_stat/user_stat_screen.dart (1)

115-120: Consider optimizing stats retrieval and improving error handling

The current implementation has a few areas for improvement:

  1. The same iteration pattern is repeated twice
  2. Silent fallbacks to empty stats might mask data loading issues

Consider refactoring to:

-    final testStats = state.userStats
-            ?.firstWhere((element) => element.type == UserStatType.test) ??
-        UserStat();
-    final otherStats = state.userStats
-            ?.firstWhere((element) => element.type == UserStatType.other) ??
-        UserStat();
+    final stats = state.userStats?.fold<Map<UserStatType, UserStat>>(
+      {UserStatType.test: UserStat(), UserStatType.other: UserStat()},
+      (map, stat) => map..[stat.type] = stat,
+    ) ?? {UserStatType.test: UserStat(), UserStatType.other: UserStat()};
+    
+    final testStats = stats[UserStatType.test]!;
+    final otherStats = stats[UserStatType.other]!;

This approach:

  • Reduces iterations through userStats
  • Makes the default values more explicit
  • Maintains the same functionality while being more efficient
data/lib/api/tournament/tournament_model.dart (1)

139-140: Consider adding null safety checks for stats properties.

While the code assumes the presence of batting and bowling stats, it might be safer to add null checks to handle cases where these stats might not be initialized yet.

-      final battingStats = playerStat.stats.batting;
-      final bowlingStats = playerStat.stats.bowling;
+      final battingStats = playerStat.stats.batting;
+      final bowlingStats = playerStat.stats.bowling;
+      
+      // Skip if required stats are not available
+      if (battingStats == null || bowlingStats == null) continue;
khelo/lib/ui/flow/team/user_detail/user_detail_screen.dart (1)

170-175: Consider optimizing stats retrieval and null handling.

The current implementation has a few potential improvements:

  1. Using firstWhere on potentially large lists could be inefficient.
  2. Creating new UserStat instances as fallbacks could be wasteful.

Consider this alternative approach:

-    final testStats = state.userStats
-            ?.firstWhere((element) => element.type == UserStatType.test) ??
-        UserStat();
-    final otherStats = state.userStats
-            ?.firstWhere((element) => element.type == UserStatType.other) ??
-        UserStat();
+    // Cache the stats list to avoid multiple null checks
+    final stats = state.userStats;
+    // Use a shared empty stat instance
+    static final _emptyStats = UserStat();
+    
+    final testStats = stats?.firstWhere(
+      (element) => element.type == UserStatType.test,
+      orElse: () => _emptyStats,
+    ) ?? _emptyStats;
+    
+    final otherStats = stats?.firstWhere(
+      (element) => element.type == UserStatType.other,
+      orElse: () => _emptyStats,
+    ) ?? _emptyStats;
khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_stats_tab.dart (1)

Line range hint 132-141: Consider enhancing statistics display robustness

The current implementation could benefit from several improvements:

  1. Add error boundaries to gracefully handle statistics calculation failures
  2. Extract number formatting logic into a utility function for consistency
  3. Consider adding loading states while statistics are being calculated

Consider creating a utility class for statistics formatting:

class StatisticsFormatter {
  static String formatAverage(double? value) {
    return value?.toStringAsFixed(1) ?? '0.0';
  }
  
  static String formatRuns(int? value) {
    return value?.toString() ?? '0';
  }
}

Then use it in the widget:

-    final average = keyStat.stats.bowling.average.toStringAsFixed(1);
-    final runs = keyStat.stats.batting.runScored.toString();
+    final average = StatisticsFormatter.formatAverage(keyStat.stats.bowling?.average);
+    final runs = StatisticsFormatter.formatRuns(keyStat.stats.batting?.runScored);
khelo/lib/ui/flow/team/user_detail/user_detail_view_model.freezed.dart (1)

210-219: Consider optimizing the getter implementation

While the implementation is functionally correct, it could be optimized by reducing the number of checks:

  List<UserStat>? get userStats {
-   final value = _userStats;
-   if (value == null) return null;
-   if (_userStats is EqualUnmodifiableListView) return _userStats;
+   if (_userStats == null) return null;
+   if (_userStats is EqualUnmodifiableListView) return _userStats;
    // ignore: implicit_dynamic_type
-   return EqualUnmodifiableListView(value);
+   return EqualUnmodifiableListView(_userStats!);
  }
khelo/lib/ui/flow/stats/user_stat/user_stat_view_model.dart (2)

51-55: Correct the class name in the debug print statement

The debug print statement references UserDetailViewNotifier, but the class is UserStatViewNotifier. Updating the class name in the log will ensure accurate and consistent logging.

Apply this diff to correct the class name:

   }, onError: (e) {
     state = state.copyWith(loading: false, error: e);
-    debugPrint("UserDetailViewNotifier: error while loading data -> $e");
+    debugPrint("UserStatViewNotifier: error while loading data -> $e");
   });

78-78: Initialize userStats with an empty list instead of null

Initializing userStats to an empty list ([]) rather than null can help avoid potential null reference errors and eliminates the need for null checks elsewhere in the code.

Apply this diff to initialize userStats to an empty list:

-        @Default(null) List<UserStat>? userStats,
+        @Default([]) List<UserStat> userStats,
khelo/lib/ui/flow/team/user_detail/user_detail_view_model.dart (1)

85-85: Initialize userStats with an empty list instead of null

Currently, userStats is initialized with @Default(null) and is nullable. For consistency and to simplify null checks, consider initializing it with an empty list using @Default([]) and making the type non-nullable.

Apply this diff to initialize userStats with an empty list:

-    @Default(null) List<UserStat>? userStats,
+    @Default([]) List<UserStat> userStats,
data/lib/service/user/user_service.dart (2)

64-67: Consider adding pagination to the migrate method to handle large datasets

Fetching all users without pagination might lead to performance issues if the number of users is large. Consider implementing pagination to fetch users in batches to prevent potential memory and resource exhaustion.


183-199: Consider consolidating createNewUser and _createUser to avoid duplication

Both methods serve to create a new user. Consolidating them can adhere to the DRY (Don't Repeat Yourself) principle and maintain a single source of truth for user creation logic.

data/lib/api/user/user_models.dart (4)

244-337: Inconsistent naming of extension: 'UserStatsExtension'

The extension is named UserStatsExtension but extends the UserStat class. For consistency and clarity, it's better to name the extension UserStatExtension to match the class it extends.

Apply this diff to rename the extension:

-extension UserStatsExtension on UserStat {
+extension UserStatExtension on UserStat {

173-192: Missing or incorrect JSON annotations for UserStat class

The @JsonSerializable annotation is placed after the @freezed decorator, which might lead to improper JSON serialization. According to best practices with the freezed package, the @JsonSerializable annotation should be placed directly above the class declaration.

Apply this diff to reposition the annotation:

 @freezed
+@JsonSerializable(anyMap: true, explicitToJson: true)
 class UserStat with _$UserStat {
-  @JsonSerializable(anyMap: true, explicitToJson: true)
   const factory UserStat({
     @Default(0) int matches,
     UserStatType? type,
     @Default(Batting()) Batting batting,
     @Default(Bowling()) Bowling bowling,
     @Default(Fielding()) Fielding fielding,
   }) = _UserStat;

This ensures that the JSON serialization behaves as expected when using freezed.


194-242: Consider adding validation for statistical fields

The statistical fields in Batting, Bowling, and Fielding classes are currently not validated for negative values. Since negative statistics (e.g., negative runs, wickets) are not logical in this context, adding validation checks can prevent erroneous data.

You might consider adding assertions or validation logic to ensure that these fields remain non-negative.


245-287: Enhance null safety in statistical aggregation methods

In the aggregation methods _addBattingStats, _addBowlingStats, and _addFieldingStats, the null checks might be unnecessary since the fields have default values and are non-nullable due to the @Default annotation.

Simplify the code by removing null checks:

-  if (oldBatting == null) return newBatting!;
-  if (newBatting == null) return oldBatting;

Since Batting instances are expected to be non-null, you can remove these checks to streamline the code.

khelo/lib/ui/flow/score_board/score_board_view_model.dart (10)

14-14: Consider removing unused imports.

The import statement for package:khelo/domain/extensions/context_extensions.dart on line 14 seems to be unused in this file. Removing unused imports can help keep the code clean and improve compilation times.

Apply this diff to remove the unused import:

- import 'package:khelo/domain/extensions/context_extensions.dart';

29-29: Ensure consistency in provider dependency injection.

In the scoreBoardStateProvider, the BallScoreService is injected after the UserService. However, in the ScoreBoardViewNotifier constructor, the parameters are ordered differently. Consider maintaining a consistent order of dependencies to improve readability and reduce confusion.

Here's the constructor for reference:

ScoreBoardViewNotifier(
  this._matchService,
  this._inningService,
  this._userService,
  this._ballScoreService,
)

Ensure the order of parameters matches in both places.


37-37: Consider making _userService a late final variable.

The _userService is declared as:

final UserService _userService;

Since it's injected via the constructor and never reassigned, you might consider declaring it as a late final variable for clarity.

late final UserService _userService;

49-49: Possible redundant constructor parameters.

The constructor of ScoreBoardViewNotifier takes _ballScoreService after _userService, but their order differs from the provider declaration. Ensure that the parameters are in the same order as in the provider for consistency.

Ensure the constructor parameters match the order of dependencies injected in the provider.


773-794: Handle asynchronous errors when updating player stats.

In the _addPlayerStats method, you are catching all exceptions broadly. While this prevents the app from crashing, it might mask underlying issues. Consider handling specific exceptions to provide more granularity.

Additionally, ensure that the UI reflects any errors so users are aware if stats fail to update.

Apply this diff to log errors with more context:

} catch (e) {
-  debugPrint(
-      "ScoreBoardViewNotifier: error while adding player stats -> $e");
+  debugPrint(
+      "ScoreBoardViewNotifier: error while adding player stats -> $e");
+  // Optionally, update state with error information
+  state = state.copyWith(
+    actionError: e,
+    isActionInProgress: false,
+  );
}

Line range hint 920-928: Potential logical error in _isTargetAchieved method for Test Matches.

In the _isTargetAchieved method, when handling MatchType.testMatch, there's a logical block:

if (state.currentInning?.index == 3 ||
    state.currentInning?.index == 4) {
  //...
}

Within this block, you check if secondPlayingTeam.run > firstPlayingTeam.run, but run might not reflect the total runs if innings are incomplete.

Verify that the run comparison accurately reflects the match state, especially considering draws or follow-on scenarios in Test cricket.


Line range hint 1086-1099: Incorrect use of break in onMatchOptionSelect switch-case.

In the onMatchOptionSelect method, after each case, there is no break statement. In Dart, unlike some other languages, the switch statement doesn't require break, but using return or arranging the code appropriately is important.

Ensure that each case correctly handles the intended action without falling through unintentionally.

Example:

switch (option) {
  case MatchOption.changeStriker:
    _showStrikerSelectionSheet();
    break;
  case MatchOption.pauseScoring:
    state = state.copyWith(showPauseScoringSheet: DateTime.now());
    break;
  // ...
}

Consider adding break or return statements to prevent unintended fall-through.


Line range hint 1377-1387: Potential issue with overwriting state in _configureScoringDetails.

After setting several properties on state, you immediately overwrite state again. This can lead to lost updates.

Consider combining the updates into a single copyWith or ensuring that subsequent updates include all necessary properties.


Line range hint 1510-1528: Redundant check and potential dead code in _isMatchTied method.

In the _isMatchTied method under MatchType.testMatch, the condition:

if (state.currentInning?.index == 4 && _isAllOut()) {
  //...
} else {
  return false;
}

Since the if block returns a value, the else is redundant.

Simplify the code by removing unnecessary else statements.

if (state.currentInning?.index == 4 && _isAllOut()) {
  //...
}
return false;

Line range hint 2014-2033: Handling of active players in getFilteredPlayerList.

In the getFilteredPlayerList method, you're filtering players based on their status. Ensure that players who are suspended or injured are correctly excluded from the list when selecting batsmen or bowlers.

Verify that the logic accurately reflects the game's rules and that players who should not be selectable are properly filtered out.

data/lib/api/user/user_models.freezed.dart (5)

1141-1150: Rename 'runScored' to 'runsScored' for consistency

In the Batting class, the field runScored represents the total runs scored by a player. For consistency and clarity, consider renaming it to runsScored to match the plural form used in similar fields like runsConceded in the Bowling class.


1145-1145: Rename 'ballFaced' to 'ballsFaced' for grammatical correctness

In the Batting class, the field ballFaced should be pluralized to ballsFaced to accurately represent that it refers to multiple balls faced by the player.


1485-1495: Pluralize 'wicketTaken' to 'wicketsTaken'

In the Bowling class, the field wicketTaken represents the number of wickets taken by a player. For grammatical correctness and to indicate that it can be multiple wickets, consider renaming it to wicketsTaken.


1841-1843: Pluralize 'runOut' to 'runOuts' in the 'Fielding' class

In the Fielding class, the field runOut should be renamed to runOuts to reflect that it records the number of run-outs achieved by a player.


1840-1842: Consider initializing Fielding stats with default values

In the Fielding class, ensure that all statistics are initialized with default values to prevent potential null reference issues when these fields are accessed.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between c477c68 and 16f76eb.

📒 Files selected for processing (22)
  • data/.flutter-plugins-dependencies (1 hunks)
  • data/lib/api/ball_score/ball_score_model.dart (7 hunks)
  • data/lib/api/ball_score/ball_score_model.freezed.dart (0 hunks)
  • data/lib/api/ball_score/ball_score_model.g.dart (0 hunks)
  • data/lib/api/tournament/tournament_model.dart (1 hunks)
  • data/lib/api/user/user_models.dart (1 hunks)
  • data/lib/api/user/user_models.freezed.dart (1 hunks)
  • data/lib/api/user/user_models.g.dart (1 hunks)
  • data/lib/service/user/user_service.dart (3 hunks)
  • data/lib/utils/constant/firestore_constant.dart (2 hunks)
  • khelo/lib/ui/flow/score_board/score_board_view_model.dart (4 hunks)
  • khelo/lib/ui/flow/stats/user_stat/user_stat_screen.dart (2 hunks)
  • khelo/lib/ui/flow/stats/user_stat/user_stat_view_model.dart (5 hunks)
  • khelo/lib/ui/flow/stats/user_stat/user_stat_view_model.freezed.dart (11 hunks)
  • khelo/lib/ui/flow/team/user_detail/component/user_detail_batting_content.dart (2 hunks)
  • khelo/lib/ui/flow/team/user_detail/component/user_detail_bowling_content.dart (2 hunks)
  • khelo/lib/ui/flow/team/user_detail/component/user_detail_fielding_content.dart (3 hunks)
  • khelo/lib/ui/flow/team/user_detail/user_detail_screen.dart (3 hunks)
  • khelo/lib/ui/flow/team/user_detail/user_detail_view_model.dart (2 hunks)
  • khelo/lib/ui/flow/team/user_detail/user_detail_view_model.freezed.dart (13 hunks)
  • khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_stats_tab.dart (1 hunks)
  • khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.dart (1 hunks)
💤 Files with no reviewable changes (2)
  • data/lib/api/ball_score/ball_score_model.freezed.dart
  • data/lib/api/ball_score/ball_score_model.g.dart
✅ Files skipped from review due to trivial changes (1)
  • data/.flutter-plugins-dependencies
🔇 Additional comments (44)
khelo/lib/ui/flow/team/user_detail/component/user_detail_fielding_content.dart (2)

Line range hint 1-6: LGTM! Imports and class declaration are well structured.

The imports are appropriate and the class correctly extends ConsumerWidget for state management with Riverpod.


Line range hint 10-19: Verify the properties of the new Fielding type.

The change from FieldingStat? to Fielding? looks correct, but we should verify that all required properties (catches, runOut, stumping) are available in the new type.

✅ Verification successful

Type change from FieldingStat to Fielding is safe and maintains all required properties

The new Fielding class in data/lib/api/user/user_models.dart contains all the necessary properties (catches, runOut, stumping) with the same names and types. The usage in user_detail_fielding_content.dart shows these properties are being accessed correctly. The change is verified to be type-compatible.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the structure of the new Fielding class
# Expected: Should find the definition of Fielding class with required properties

ast-grep --pattern 'class Fielding {
  $$$
}'

# Also check for any remaining references to the old FieldingStat type
rg "FieldingStat" 

Length of output: 569


Script:

#!/bin/bash
# Let's check the Fielding class definition in the data models
rg -A 10 "^class Fielding" 

# Also check for any usages of fielding properties
rg "\.(catches|runOut|stumping)"

Length of output: 4934

data/lib/utils/constant/firestore_constant.dart (1)

32-32: Clarify the purpose of the type field

The constant type is quite generic and its purpose is unclear. Since it's placed in the matches field constants section, consider using a more specific name that indicates its intended use (e.g., matchType, gameType).

✅ Verification successful

Let me search for more context about how this field is used.


Let me try a different approach to find more context.


Let me search for the match model to understand how the type field is used.


Based on the search results, I can now provide a final response:

The type field is used for match type classification

The constant type in FirestoreConstant is used to store the match type in the Firestore database. This is evident from the codebase where match types are handled through MatchType enum, as seen in the match service where matches are created with types like MatchType.limitedOvers. The field name is consistent with Firestore's naming conventions and is appropriately placed in the matches field constants section.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usages of the 'type' field to understand its context
rg -A 3 '"type"' --type dart

Length of output: 329


Script:

#!/bin/bash
# Search for usages of FirestoreConstant.type to understand its usage
rg -A 3 "FirestoreConstant.type" --type dart

# Also search for any matches-related code to understand the context
ast-grep --pattern 'class $_ {
  $$$
  match$_($$$) {
    $$$
  }
  $$$
}'

Length of output: 121


Script:

#!/bin/bash
# Get more context around the type constant by showing the entire file
cat data/lib/utils/constant/firestore_constant.dart

# Search for any Firestore-related operations that might use this field
rg -A 5 "\.collection|\.document" --type dart

Length of output: 9898


Script:

#!/bin/bash
# Search for MatchModel class definition and its usage of the type field
ast-grep --pattern 'class MatchModel {
  $$$
}'

# Also search for any references to type in match-related files
rg -A 3 "type.*=|type:" --type dart data/lib/

Length of output: 44555

khelo/lib/ui/flow/team/user_detail/component/user_detail_batting_content.dart (2)

Line range hint 22-89: LGTM! Well-structured UI implementation

The build method implementation is well-organized with:

  • Proper null safety handling
  • Consistent decimal formatting for floating-point values
  • Good use of internationalization
  • Clean separation of test and other match statistics

10-11: Verify type migration completeness

The change from BattingStat? to Batting? type needs verification to ensure all required properties are available in the new Batting class.

✅ Verification successful

Let me modify the script to correctly search for property accesses and class definition.


Let me search for the old BattingStat class to compare its properties with the new Batting class.


Based on the gathered information, I can now provide the final response:

Type migration from BattingStat to Batting is properly implemented

The new Batting class in data/lib/api/user/user_models.dart contains all necessary properties to support the existing usage. The properties accessed in the codebase (matches, batting, bowling, fielding) are properly handled, and the new class includes comprehensive batting statistics (innings, runScored, average, strikeRate, etc.). The migration appears complete with proper data conversion methods in place.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Compare the properties used in this file with the new Batting class definition

# First, collect all the properties accessed on testStats and otherStats
echo "Properties used in this file:"
rg -o 'test(Stats|Stats\?)\.\K\w+' . | sort -u
rg -o 'other(Stats|Stats\?)\.\K\w+' . | sort -u

# Then, check the definition of the new Batting class
echo -e "\nBatting class definition:"
ast-grep --pattern 'class Batting {
  $$$
}'

Length of output: 511


Script:

#!/bin/bash
# Search for property accesses on testStats and otherStats
echo "Properties accessed on testStats:"
rg "testStats\.[a-zA-Z]+" --only-matching

echo -e "\nProperties accessed on otherStats:"
rg "otherStats\.[a-zA-Z]+" --only-matching

echo -e "\nBatting class definition and usage:"
# Find Batting class definition
rg "class Batting" -A 20

# Also search for any imports related to Batting
rg "import.*Batting"

Length of output: 3172


Script:

#!/bin/bash
# Search for the old BattingStat class definition
echo "Old BattingStat class definition:"
rg "class BattingStat" -A 20

# Search for any files that might still be using BattingStat
echo -e "\nFiles still using BattingStat:"
rg "BattingStat"

Length of output: 689

khelo/lib/ui/flow/team/user_detail/component/user_detail_bowling_content.dart (2)

Line range hint 23-115: Implementation looks solid and follows best practices!

The widget implementation demonstrates:

  • Proper null-safety handling
  • Consistent decimal formatting
  • Clean UI structure with proper spacing
  • Good use of localization
  • Reusable row creation logic

11-12: Verify the type change from BowlingStat to Bowling

The type change looks consistent with the refactoring mentioned in the PR objectives. However, let's ensure all usages are updated correctly.

✅ Verification successful

Type change from BowlingStat to Bowling is correctly implemented

The verification shows that:

  1. The Bowling class is properly defined in user_models.dart with all necessary fields
  2. The type change is consistently implemented across the codebase
  3. The helper method _addBowlingStats in user_models.dart already uses the Bowling type
  4. No legacy BowlingStat type references remain that would conflict with this change
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining references to BowlingStat
# and verify consistent usage of the new Bowling type

# Search for any remaining BowlingStat references
echo "Checking for any remaining BowlingStat references:"
rg "BowlingStat" -l

# Search for the new Bowling type usage pattern
echo "Checking Bowling type usage pattern:"
rg "Bowling\?" -l

Length of output: 427


Script:

#!/bin/bash
# Let's examine the content of these files to understand the type definitions and usage

# Check the model definitions in user_models.dart
echo "=== Examining user_models.dart ==="
rg "class.*Bowling" -A 5 data/lib/api/user/user_models.dart

# Check if BowlingStat is being used as a type or is it being migrated
echo -e "\n=== Checking BowlingStat usage in user_models.dart ==="
rg "BowlingStat" -A 3 data/lib/api/user/user_models.dart

# Check BowlingStat usage in ball_score_model.dart
echo -e "\n=== Checking BowlingStat in ball_score_model.dart ==="
rg "BowlingStat" -A 3 data/lib/api/ball_score_model.dart

# Check how Bowling type is used in the widget file
echo -e "\n=== Examining usage in user_detail_bowling_content.dart ==="
rg "Bowling\?" -A 3 khelo/lib/ui/flow/team/user_detail/component/user_detail_bowling_content.dart

Length of output: 1399

khelo/lib/ui/flow/stats/user_stat/user_stat_screen.dart (2)

128-143: LGTM! Clean and consistent implementation

The parameter passing to content widgets is well-structured and consistent. The code:

  • Maintains a clear separation of concerns
  • Properly handles both test and other match statistics
  • Follows a consistent pattern across batting, bowling, and fielding components

128-143: Verify content widgets compatibility with new stat models

Since this is part of a larger refactor that introduced new stat models, we should verify that the content widgets are updated to handle the new types correctly.

✅ Verification successful

Based on the output, I can now generate the final response as we have found all the necessary information. The content widgets are properly updated to handle the new model types:

Content widgets are correctly using the new stat models

All three content widgets (UserDetailBattingContent, UserDetailBowlingContent, and UserDetailFieldingContent) are properly importing and using the correct model types from package:data/api/user/user_models.dart:

  • UserDetailBattingContent uses Batting? type for stats
  • UserDetailBowlingContent uses Bowling? type for stats
  • UserDetailFieldingContent uses Fielding? type for stats
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the content widgets are updated to use the new model types
ast-grep --pattern 'class UserDetailBattingContent {
  $$$
  final Batting? testStats;
  $$$
}'

ast-grep --pattern 'class UserDetailBowlingContent {
  $$$
  final Bowling? testStats;
  $$$
}'

ast-grep --pattern 'class UserDetailFieldingContent {
  $$$
  final Fielding? testStats;
  $$$
}'

Length of output: 295


Script:

#!/bin/bash
# Let's try to find these content widgets first
fd "user_detail.*content\.dart" --type f --exec cat {}

# Also search for any imports of the stat models
rg "import.*user_models" -A 2

Length of output: 30762

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

139-140: LGTM! Verify the property access changes across the codebase.

The refactoring from battingStat/bowlingStat to batting/bowling improves naming consistency. However, we should ensure all references are updated.

✅ Verification successful

Let me search for any other occurrences of these property accesses to ensure we haven't missed any patterns.


Property access changes are consistent across the codebase

The search results confirm that all references to batting and bowling statistics consistently use the new stats.batting and stats.bowling pattern. The changes in tournament_model.dart align with the usage patterns in other files (tournament_detail_view_model.dart and tournament_detail_stats_tab.dart), showing a uniform approach to accessing these properties.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining old property references
rg "battingStat|bowlingStat" --type dart

Length of output: 1356


Script:

#!/bin/bash
# Search for any references to batting/bowling stats in dart files
rg -A 2 "stats\.(batting|bowling)" --type dart

Length of output: 4693

khelo/lib/ui/flow/team/user_detail/user_detail_screen.dart (2)

1-1: LGTM: Import aligns with the new user stats model.

The addition of the user models import supports the refactored user statistics implementation.


187-196: Verify null handling in child components.

The stats are correctly passed to the batting and bowling components. However, we should ensure that these components handle potentially null stats gracefully.

Let's check the implementation of these components:

✅ Verification successful

Let me try a different approach to find these components and their implementations.


Let me check the actual implementation of these components to see how they handle null stats.


Null handling is properly implemented in both components

Both UserDetailBattingContent and UserDetailBowlingContent handle null stats appropriately:

  1. The stats parameters (testStats and otherStats) are properly declared as nullable types (Batting? and Bowling?)
  2. When accessing stats properties, the null-safe operator (?) is used consistently (e.g., testStats?.innings.toString())
  3. The statsDataRow helper function handles null values by providing a default '0' value: subtitle1 ?? '0'
  4. Match counts have default values of 0 in the constructor parameters
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check how UserDetailBattingContent and UserDetailBowlingContent handle null stats

# Search for null checks in the batting component
echo "Checking UserDetailBattingContent..."
ast-grep --pattern 'class UserDetailBattingContent {
  $$$
}'

# Search for null checks in the bowling component
echo "Checking UserDetailBowlingContent..."
ast-grep --pattern 'class UserDetailBowlingContent {
  $$$
}'

Length of output: 293


Script:

#!/bin/bash
# Search for files containing UserDetailBattingContent or UserDetailBowlingContent
echo "Searching for component files..."
fd -e dart | xargs rg "UserDetailBattingContent|UserDetailBowlingContent" -B 2 -A 10

# Also search for required parameters in these components
echo "Searching for required parameters..."
rg "@required.*Stats" -A 2

Length of output: 7725


Script:

#!/bin/bash
# Get the full implementation of both components
echo "UserDetailBattingContent implementation:"
cat khelo/lib/ui/flow/team/user_detail/component/user_detail_batting_content.dart

echo -e "\nUserDetailBowlingContent implementation:"
cat khelo/lib/ui/flow/team/user_detail/component/user_detail_bowling_content.dart

Length of output: 8705

khelo/lib/ui/flow/stats/user_stat/user_stat_view_model.freezed.dart (5)

Line range hint 61-73: LGTM! Proper null-safety implementation

The copy method implementation correctly handles the nullable List<UserStat>? while maintaining immutability.


139-157: LGTM! Proper immutability implementation

The implementation correctly ensures immutability of the stats list using EqualUnmodifiableListView while maintaining proper null-safety.


165-165: LGTM! Proper equality implementations

The toString, equals, and hashCode implementations correctly handle the list property using DeepCollectionEquality for proper collection comparison.

Also applies to: 176-177, 186-186


203-203: LGTM! Verify broader refactoring impact

The abstract class declarations are consistent. However, since this is part of a larger refactoring effort replacing multiple stat properties with a consolidated list, we should verify the impact on dependent code.

Also applies to: 211-211

✅ Verification successful

Properties are correctly used after refactoring

The search results show that the old stat properties (testStats, otherStats, etc.) are being used correctly in the UI components. The code extracts these values from the consolidated userStats list by filtering on UserStatType, which aligns with the refactoring:

  • user_detail_screen.dart and user_stat_screen.dart properly extract stats using firstWhere on UserStatType
  • Component files (user_detail_batting_content.dart, user_detail_bowling_content.dart, user_detail_fielding_content.dart) correctly receive and display the extracted stats
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential usage of old stat properties in the codebase
rg -A 3 "testStats|otherStats|testMatchesCount|otherMatchesCount"

Length of output: 21787


21-21: Verify UserStat type import

The consolidation of stats into a List<UserStat>? improves maintainability. However, let's verify the UserStat type import.

✅ Verification successful

UserStat type is properly imported and used

The verification shows that:

  1. UserStat class is properly defined in data/lib/api/user/user_models.dart
  2. The view model correctly imports it via import 'package:data/api/user/user_models.dart'
  3. The freezed file is generated from the view model, so it inherits the imports

The consolidation of multiple stat properties into a List<UserStat>? is well-structured and properly typed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if UserStat type is properly imported and defined
rg -l "class UserStat" 

Length of output: 175


Script:

#!/bin/bash
# Check imports in the freezed file and the actual model file
echo "=== Checking imports in user_stat_view_model.freezed.dart ==="
rg "import.*UserStat" khelo/lib/ui/flow/stats/user_stat/user_stat_view_model.freezed.dart

echo -e "\n=== Checking UserStat definition ==="
rg "class UserStat" -A 5 data/lib/api/user/user_models.dart khelo/lib/ui/flow/stats/user_stat/user_stat_screen.dart khelo/lib/ui/flow/stats/user_stat/user_stat_view_model.dart

Length of output: 2550


Script:

#!/bin/bash
# Let's verify the import in the actual view model file and check if UserStat is properly imported there
echo "=== Checking imports in the original view model file ==="
rg "import.*UserStat|import.*user_models" khelo/lib/ui/flow/stats/user_stat/user_stat_view_model.dart

echo -e "\n=== Checking if freezed file imports from the view model ==="
rg "import.*user_stat_view_model\.dart" khelo/lib/ui/flow/stats/user_stat/user_stat_view_model.freezed.dart

Length of output: 522

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

133-134: Verify null safety for statistics access

The direct access to bowling.average and batting.runScored assumes these properties will always be present. This could lead to runtime errors if the statistics are null.

Let's verify the assumptions about non-null statistics:

Consider adding null safety:

-    final average = keyStat.stats.bowling.average.toStringAsFixed(1);
-    final runs = keyStat.stats.batting.runScored.toString();
+    final average = keyStat.stats.bowling?.average?.toStringAsFixed(1) ?? '0.0';
+    final runs = keyStat.stats.batting?.runScored?.toString() ?? '0';
khelo/lib/ui/flow/team/user_detail/user_detail_view_model.freezed.dart (6)

24-24: LGTM: Field declaration follows Freezed patterns

The new userStats field is correctly declared as a nullable list using Freezed's mixin pattern.


45-45: LGTM: CopyWith implementation handles nullability correctly

The CopyWith interface and implementation properly handle the nullable List<UserStat> with appropriate null safety checks using the freezed parameter.

Also applies to: 70-93


126-126: LGTM: Implementation class follows consistent patterns

The implementation correctly handles the new userStats field, maintaining consistency with other fields in the class.

Also applies to: 150-173


223-223: LGTM: Proper implementation of equality and hashing

The implementation correctly uses DeepCollectionEquality for comparing and hashing the userStats list, ensuring proper value equality.

Also applies to: 237-238, 249-249


268-268: LGTM: Abstract class maintains proper contract

The abstract class correctly defines the userStats field, maintaining consistency with the implementation.

Also applies to: 281-281


Line range hint 1-290: Verify migration from previous stats structure

Since this is generated code reflecting a change from individual match stats to a consolidated userStats list, ensure that all consumers of this view model have been updated to use the new structure.

✅ Verification successful

Migration to new stats structure is properly handled

The code shows that both user_detail_screen.dart and user_stat_screen.dart have been updated to use the new userStats list structure, correctly extracting test and other stats from it. The component files (user_detail_batting_content.dart, user_detail_bowling_content.dart, and user_detail_fielding_content.dart) still use the old property names but they are now being passed the correctly transformed data from their parent components.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining references to the old stats structure

# Search for references to removed properties
echo "Checking for references to removed properties..."
rg -l "testMatchesCount|otherMatchesCount|testStats|otherStats" --type dart

# Search for potential usage of UserDetailViewState
echo "Checking for UserDetailViewState usage..."
rg -l "UserDetailViewState" --type dart

Length of output: 860


Script:

#!/bin/bash
# Let's examine the actual usage of these properties in the files

echo "Checking user_detail_fielding_content.dart..."
rg -A 5 -B 5 "testMatchesCount|otherMatchesCount|testStats|otherStats" khelo/lib/ui/flow/team/user_detail/component/user_detail_fielding_content.dart

echo -e "\nChecking user_detail_batting_content.dart..."
rg -A 5 -B 5 "testMatchesCount|otherMatchesCount|testStats|otherStats" khelo/lib/ui/flow/team/user_detail/component/user_detail_batting_content.dart

echo -e "\nChecking user_detail_bowling_content.dart..."
rg -A 5 -B 5 "testMatchesCount|otherMatchesCount|testStats|otherStats" khelo/lib/ui/flow/team/user_detail/component/user_detail_bowling_content.dart

echo -e "\nChecking user_detail_screen.dart..."
rg -A 5 -B 5 "testMatchesCount|otherMatchesCount|testStats|otherStats" khelo/lib/ui/flow/team/user_detail/user_detail_screen.dart

echo -e "\nChecking user_stat_screen.dart..."
rg -A 5 -B 5 "testMatchesCount|otherMatchesCount|testStats|otherStats" khelo/lib/ui/flow/stats/user_stat/user_stat_screen.dart

Length of output: 10823

khelo/lib/ui/flow/stats/user_stat/user_stat_view_model.dart (1)

3-4: Updated imports align with user statistics management

The addition of user_models.dart and user_service.dart imports correctly reflects the shift towards user-focused statistics, which is appropriate for the new functionality.

khelo/lib/ui/flow/team/user_detail/user_detail_view_model.dart (2)

49-49: LGTM!

The addition of _userService.streamUserStats(_userId!) effectively incorporates user statistics into the data stream.


55-55: LGTM!

Updating the state with userStats: event.$3 appropriately reflects the inclusion of user statistics in state management.

data/lib/service/user/user_service.dart (5)

56-62: LGTM!

The _userStatsRef method is correctly implemented, providing a collection reference for UserStat with appropriate Firestore converters.


114-115: LGTM!

The code correctly queries users by phone number.


171-181: LGTM!

The getUserStats method correctly retrieves user statistics filtered by type.


201-208: LGTM!

The updateUser method correctly updates the user data with merge options.


222-230: LGTM!

The _createUser method correctly creates a new user with the necessary fields.

data/lib/api/user/user_models.g.dart (8)

122-135: Deserialization of UserStatsImpl is correctly implemented

The _$$UserStatsImplFromJson function appropriately handles the deserialization of UserStatsImpl, with correct default values and null checks for nested objects.


137-144: Serialization of UserStatsImpl is accurately handled

The _$$UserStatsImplToJson function correctly serializes the UserStatsImpl instance to JSON, ensuring all fields are properly converted.


146-149: Enum mapping for UserStatType is correctly defined

The _$UserStatTypeEnumMap accurately maps UserStatType enum values to their string representations.


151-164: Deserialization of BattingImpl handles defaults appropriately

The _$$BattingImplFromJson function correctly deserializes BattingImpl objects, implementing default values and ensuring type safety with null-aware operators.


166-177: Serialization of BattingImpl is correctly implemented

The _$$BattingImplToJson function accurately serializes BattingImpl instances, ensuring all statistical fields are included in the JSON output.


180-192: Deserialization of BowlingImpl correctly manages default values

The _$$BowlingImplFromJson function properly deserializes BowlingImpl objects, with appropriate handling of nullable fields and default values.


194-206: Serialization of BowlingImpl is accurately handled

The _$$BowlingImplToJson function correctly serializes BowlingImpl instances, ensuring all relevant bowling statistics are included.


Line range hint 208-220: Deserialization and serialization of FieldingImpl are correctly implemented

The _$$FieldingImplFromJson and _$$FieldingImplToJson functions handle the conversion of FieldingImpl objects to and from JSON accurately, with proper default values.

data/lib/api/user/user_models.dart (1)

215-230: Potential division by zero in bowling statistics calculation

In the _addBowlingStats method, while calculating economyRate, there's a multiplication by 6 (assuming overs of 6 balls). However, if combinedBalls is zero, this could lead to a division by zero error when calculating the economy rate.

Please ensure that combinedBalls is not zero before performing the division.

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

639-665: LGTM!

The calculateUserStats method correctly aggregates user statistics.

khelo/lib/ui/flow/score_board/score_board_view_model.dart (2)

Line range hint 307-317: Potential performance issue with sorting.

In the _loadBallScore method, you are sorting currentScoreList and previousScoreList using custom sort functions. Sorting can be resource-intensive on large lists. If the lists are large, consider using more efficient data structures or algorithms to handle sorted data.

[performance]

Consider whether the lists could be kept sorted as you insert elements, or whether a more efficient sorting algorithm is appropriate.


Line range hint 1117-1125: Possible null pointer exception in _handleAddingBall.

In the _handleAddingBall method, the switch statement might not handle all possible ScoreButton values, leading to potential issues if new enum values are added in the future.

Ensure all enum values are handled or include a default case to prevent runtime exceptions.

switch (btn) {
  // existing cases...
  default:
    // Handle unexpected cases or throw an error
    throw UnimplementedError('Button action not implemented for $btn');
}

data/lib/api/user/user_models.dart Outdated Show resolved Hide resolved
@canopas canopas deleted a comment from coderabbitai bot Nov 26, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 26, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 26, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 26, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 26, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 26, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 26, 2024
@cp-mayank cp-mayank marked this pull request as draft November 26, 2024 11:23
@canopas canopas deleted a comment from coderabbitai bot Nov 27, 2024
@cp-mayank cp-mayank marked this pull request as ready for review November 27, 2024 07:02
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 (8)
data/lib/api/user/user_models.dart (2)

245-254: Add documentation for the updateStat method

The updateStat method performs complex statistical calculations. Consider adding documentation to explain:

  • The purpose of the method
  • How it combines two sets of statistics
  • When it should be used

Add this documentation above the method:

+ /// Updates the current UserStat by combining it with another UserStat.
+ /// This is typically used when adding new match statistics to existing career statistics.
+ /// The method preserves the current stat type while combining all numerical values.
  UserStat updateStat(UserStat other) {

256-286: Consider extracting rate calculations into separate methods

The calculation of averages, strike rates, and economy rates in both _updateBatting and _updateBowling methods could be extracted into separate methods for better readability and maintainability.

Consider refactoring like this:

+ double _calculateBattingAverage(int runs, int dismissals) =>
+     dismissals == 0 ? 0.0 : runs / dismissals;
+
+ double _calculateBattingStrikeRate(int runs, int balls) =>
+     balls == 0 ? 0.0 : (runs / balls) * 100.0;
+
  Batting _updateBatting(Batting oldBatting, Batting newBatting) {
    // ... existing combinations ...
-   final average =
-       combinedDismissals == 0 ? 0.0 : combinedRunsScored / combinedDismissals;
-   final strikeRate = combinedBallsFaced == 0
-       ? 0.0
-       : (combinedRunsScored / combinedBallsFaced) * 100.0;
+   final average = _calculateBattingAverage(combinedRunsScored, combinedDismissals);
+   final strikeRate = _calculateBattingStrikeRate(combinedRunsScored, combinedBallsFaced);

Similar refactoring can be applied to bowling calculations.

Also applies to: 288-317

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

778-780: Extract complex conditions into named boolean getters

The complex conditions in where clauses could be more readable if extracted into named boolean getters.

Consider extracting conditions into named getters:

+  bool get isValidDeliveryForEconomyRate =>
+    extras_type == null ||
+    extras_type == ExtrasType.legBye ||
+    extras_type == ExtrasType.bye;

   final bowledBallCountForEconomyRate = deliveries
-      .where(
-        (element) => (element.extras_type == null ||
-            element.extras_type == ExtrasType.legBye ||
-            element.extras_type == ExtrasType.bye),
-      )
+      .where((element) => element.isValidDeliveryForEconomyRate)
khelo/lib/ui/flow/score_board/score_board_view_model.dart (2)

Line range hint 1124-1136: Improve error handling specificity

The error handling in both startNextInning and endMatch could be more specific about what operation failed. This would help with debugging and user feedback.

 try {
   state = state.copyWith(actionError: null, isActionInProgress: true);
   final statsUpdated = await _addPlayerStats();
   if (!statsUpdated) {
-    throw Exception("Failed to update player stats");
+    throw Exception("Failed to update player stats: Stats update returned false");
   }
 } catch (e) {
   debugPrint(
-      "ScoreBoardViewNotifier: error while start next inning -> $e");
+      "ScoreBoardViewNotifier: ${e is Exception ? e.toString() : 'Unexpected error while updating player stats'} -> $e");
   state = state.copyWith(actionError: e, isActionInProgress: false);
 }

Also applies to: 1198-1209


783-791: Improve readability of stats calculation logic

The filtering logic for player stats could be made more maintainable by extracting the conditions into named predicates.

-            .where(
-              (element) =>
-                  element.batsman_id == player ||
-                  element.bowler_id == player ||
-                  element.wicket_taker_id == player,
-            )
+            .where((element) => _isPlayerInvolved(element, player))
+
+  bool _isPlayerInvolved(BallScoreModel ball, String playerId) {
+    return ball.batsman_id == playerId ||
+           ball.bowler_id == playerId ||
+           ball.wicket_taker_id == playerId;
+  }
data/lib/api/user/user_models.freezed.dart (3)

1039-1046: Consider validating UserStatType with matches count

The matches field has a default value of 0 while type is nullable. Consider adding validation to ensure consistency between these fields, as having matches > 0 should likely correspond to a non-null type.

 @JsonSerializable(anyMap: true, explicitToJson: true)
 class _$UserStatImpl implements _UserStat {
   const _$UserStatImpl(
       {this.matches = 0,
-      this.type,
+      required this.type,
       this.batting = const Batting(),
       this.bowling = const Bowling(),
       this.fielding = const Fielding()});

1873-1876: Consider adding computed total dismissals and documentation

The fielding statistics could be enhanced with:

  1. A computed property for total dismissals
  2. Documentation for each field explaining what constitutes each type of dismissal
 mixin _$Fielding {
+  /// Number of catches taken
   int get catches => throw _privateConstructorUsedError;
+  /// Number of run outs effected
   int get runOut => throw _privateConstructorUsedError;
+  /// Number of stumpings completed
   int get stumping => throw _privateConstructorUsedError;
+  
+  /// Total number of dismissals effected
+  int get total_dismissals => catches + runOut + stumping;

Also applies to: 1980-1980


854-2053: Well-structured cricket statistics model hierarchy

The overall architecture of the statistics models is well thought out:

  • Clear separation of batting, bowling, and fielding statistics
  • Proper use of freezed for immutability
  • Good serialization setup with explicit JSON handling

The models provide a solid foundation for tracking cricket statistics. The suggested improvements around computed properties and validation would make it even more robust.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 16f76eb and ec82ede.

📒 Files selected for processing (10)
  • data/lib/api/ball_score/ball_score_model.dart (5 hunks)
  • data/lib/api/tournament/tournament_model.dart (2 hunks)
  • data/lib/api/user/user_models.dart (1 hunks)
  • data/lib/api/user/user_models.freezed.dart (1 hunks)
  • data/lib/api/user/user_models.g.dart (1 hunks)
  • khelo/lib/ui/flow/score_board/score_board_view_model.dart (6 hunks)
  • khelo/lib/ui/flow/team/user_detail/component/user_detail_batting_content.dart (4 hunks)
  • khelo/lib/ui/flow/team/user_detail/component/user_detail_bowling_content.dart (4 hunks)
  • khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_stats_tab.dart (1 hunks)
  • khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.dart (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • data/lib/api/tournament/tournament_model.dart
  • khelo/lib/ui/flow/team/user_detail/component/user_detail_bowling_content.dart
  • khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_stats_tab.dart
  • khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.dart
🔇 Additional comments (7)
khelo/lib/ui/flow/team/user_detail/component/user_detail_batting_content.dart (2)

Line range hint 1-100: Implementation looks good!

The widget implementation is clean and well-structured. The changes align well with the PR objectives of refactoring user stats classes and methods. The UI components properly handle nullable statistics and format the values appropriately.


1-1: Verify model refactoring across the codebase

The change from BattingStat to Batting type appears to be part of the larger refactoring effort. Let's ensure this change is consistent throughout the codebase.

Also applies to: 10-11

✅ Verification successful

Let me gather more context about the model changes to understand the full picture.


Let me modify the search patterns to get better results.


Model refactoring is correctly implemented

The verification shows that:

  1. The Batting class is properly defined in data/lib/api/user/user_models.dart
  2. The old BattingStat references in ball_score_model.dart are part of the calculation logic that creates the new Batting model
  3. The widget file correctly imports from user_models.dart and uses the new Batting type
  4. Other files using batting statistics have also been updated to use the new model
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining references to the old BattingStat type
rg "BattingStat" 

# Search for usage of the new Batting type to ensure consistent adoption
rg "Batting\?" 

Length of output: 536


Script:

#!/bin/bash
# Check the implementation of Batting model
ast-grep --pattern 'class Batting'

# Check imports in the widget file to understand the model dependencies
rg -l "import.*ball_score_model\.dart" khelo/lib/ui/flow/team/user_detail/component/user_detail_batting_content.dart

# Check if there are any other files using the Batting model
rg -l "import.*user_models\.dart.*\n.*Batting" --type dart

Length of output: 408


Script:

#!/bin/bash
# Check the Batting model definition
rg "class Batting" -A 5

# Check all files importing user_models.dart
rg -l "import.*user_models\.dart"

# Check files importing ball_score_model.dart
rg -l "import.*ball_score_model\.dart"

Length of output: 5271

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

639-665: LGTM! Well-structured user stats calculation.

The method effectively combines batting, bowling, and fielding statistics while properly handling unique match counting and optional parameter cases.


Line range hint 846-871: LGTM! Clean implementation of fielding statistics.

The method correctly handles different types of dismissals and properly aggregates fielding statistics.

data/lib/api/user/user_models.g.dart (3)

151-179: Ensure correct handling of calculations in BattingImpl

The BattingImpl class and its serialization methods are correctly implemented. Please ensure that calculations involving fields like average and strike_rate handle division by zero appropriately in the business logic to prevent runtime exceptions.


181-208: Verify calculations in BowlingImpl for potential divide-by-zero errors

In the BowlingImpl class, ensure that calculations for average, strike_rate, and economy_rate properly handle cases where division by zero could occur, avoiding runtime errors.


209-221: FieldingImpl serialization is correctly implemented

The FieldingImpl class and its serialization methods appear to be correctly implemented.

@canopas canopas deleted a comment from coderabbitai bot Nov 27, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 27, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 27, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 27, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 27, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 27, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 27, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 27, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 27, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 27, 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 (4)
data/lib/api/ball_score/ball_score_model.dart (3)

639-658: Add documentation and improve null-safety

Consider adding documentation to explain the purpose of each parameter and return value. Also, consider making the type parameter non-nullable if it's required for all stat calculations.

+ /// Calculates user statistics for cricket performance
+ /// 
+ /// [currentUserId] The ID of the user whose stats are being calculated
+ /// [oldUserStats] Optional previous stats to update
+ /// [type] The type of statistics being tracked
+ /// [isMatchComplete] Whether the match is finished
+ /// Returns updated or new UserStat object
  UserStat calculateUserStats(
    String currentUserId, {
    UserStat? oldUserStats,
-   UserStatType? type,
+   required UserStatType type,
    bool isMatchComplete = false,
  })

762-765: Refactor duplicate delivery type conditions

Consider extracting the repeated conditions for legal deliveries and extras into helper methods or constants to improve maintainability and reduce duplication.

+ /// Returns true if the delivery is a legal delivery for bowling stats
+ bool isLegalDeliveryForBowling() {
+   return extras_type != ExtrasType.penaltyRun &&
+          wicket_type != WicketType.retired &&
+          wicket_type != WicketType.retiredHurt &&
+          wicket_type != WicketType.timedOut;
+ }

+ /// Returns true if the delivery should be counted for economy rate
+ bool isValidForEconomyRate() {
+   return extras_type == null ||
+          extras_type == ExtrasType.legBye ||
+          extras_type == ExtrasType.bye;
+ }

Also applies to: 771-773


Line range hint 839-864: Optimize fielding statistics calculation

Consider combining the three separate where iterations into a single pass through the deliveries to improve performance, especially for large datasets.

  Fielding calculateFieldingStats(String currentUserId) {
+   int catches = 0, runOuts = 0, stumpings = 0;
+   
+   for (final element in this) {
+     if (element.wicket_taker_id != currentUserId) continue;
+     
+     switch (element.wicket_type) {
+       case WicketType.caught:
+       case WicketType.caughtBehind:
+       case WicketType.caughtAndBowled:
+         catches++;
+         break;
+       case WicketType.runOut:
+         runOuts++;
+         break;
+       case WicketType.stumped:
+         stumpings++;
+         break;
+       default:
+         break;
+     }
+   }
+   
+   return Fielding(
+     catches: catches,
+     runOut: runOuts,
+     stumping: stumpings,
+   );
khelo/lib/ui/flow/score_board/score_board_view_model.dart (1)

29-29: LGTM! Consider reordering service initialization.

The addition of UserService as a dependency is well-structured. However, consider reordering the service initialization in the provider to group related services together.

return ScoreBoardViewNotifier(
    ref.read(matchServiceProvider),
    ref.read(inningServiceProvider),
-   ref.read(userServiceProvider),
    ref.read(ballScoreServiceProvider),
+   ref.read(userServiceProvider),
);

Also applies to: 37-37, 49-49

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between ec82ede and 4cd3df3.

📒 Files selected for processing (2)
  • data/lib/api/ball_score/ball_score_model.dart (5 hunks)
  • khelo/lib/ui/flow/score_board/score_board_view_model.dart (6 hunks)
🔇 Additional comments (5)
data/lib/api/ball_score/ball_score_model.dart (2)

726-726: Fix incorrect duck calculation logic

The current logic counts innings with 0-2 runs as ducks, which is incorrect. In cricket, a duck occurs only when a batsman is dismissed for 0 runs.


831-833: Fix maiden over calculation to check for legal deliveries

The current logic doesn't verify if all 6 balls in the over are legal deliveries. A maiden over must consist of 6 legal deliveries with no runs scored.

khelo/lib/ui/flow/score_board/score_board_view_model.dart (3)

1133-1133: ⚠️ Potential issue

Await the player stats update

The call to _addPlayerStats() should be awaited to prevent race conditions and ensure stats are updated before proceeding with the inning change.

-      _addPlayerStats();
+      final statsUpdated = await _addPlayerStats();
+      if (!statsUpdated) {
+        throw Exception("Failed to update player stats");
+      }

Likely invalid or redundant comment.


1206-1206: ⚠️ Potential issue

Await the player stats update

Similar to the previous issue, the call to _addPlayerStats() in endMatch should be awaited.

-      _addPlayerStats(isMatchComplete: true);
+      final statsUpdated = await _addPlayerStats(isMatchComplete: true);
+      if (!statsUpdated) {
+        throw Exception("Failed to update player stats");
+      }

Likely invalid or redundant comment.


775-801: ⚠️ Potential issue

Critical issues in player stats update logic

The _addPlayerStats method has several issues that need to be addressed:

  1. Error handling is insufficient - errors are only logged but not propagated
  2. The method is called but not awaited in startNextInning and endMatch
  3. Missing null safety checks for state.match?.players
  4. No return value to indicate success/failure to callers

Consider applying these improvements:

-  void _addPlayerStats({bool isMatchComplete = false}) async {
+  Future<bool> _addPlayerStats({bool isMatchComplete = false}) async {
   try {
+    if (state.match?.players == null) {
+      return false;
+    }
     final userStatType = state.match?.match_type == MatchType.testMatch
         ? UserStatType.test
         : UserStatType.other;
     for (final player in state.match?.players ?? []) {
       final oldStats = await _userService.getUserStats(player, userStatType);
       final newState = state.currentScoresList
           .where(
             (element) =>
                 element.batsman_id == player ||
                 element.bowler_id == player ||
                 element.wicket_taker_id == player,
           )
           .toList()
           .calculateUserStats(player,
               oldUserStats: oldStats, type: userStatType);
       await _userService.updateUserStats(player, newState);
     }
+    return true;
   } catch (e) {
     debugPrint(
         "ScoreBoardViewNotifier: error while adding player stats -> $e");
+    state = state.copyWith(actionError: e);
+    return false;
   }
 }

Likely invalid or redundant comment.

@canopas canopas deleted a comment from coderabbitai bot Nov 27, 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: 1

🧹 Outside diff range and nitpick comments (4)
data/lib/api/ball_score/ball_score_model.dart (4)

639-658: Add documentation and improve null-safety.

Consider adding documentation to explain the purpose of each parameter and return value. Also, the null-safety could be improved.

+  /// Calculates user statistics for batting, bowling, and fielding.
+  /// 
+  /// Parameters:
+  /// - currentUserId: The ID of the user whose stats are being calculated
+  /// - oldUserStats: Optional previous stats to be updated
+  /// - type: Optional type of the statistics
+  /// - isMatchComplete: Whether the match is complete (defaults to false)
+  /// 
+  /// Returns a new or updated UserStat object.
   UserStat calculateUserStats(
     String currentUserId, {
     UserStat? oldUserStats,
     UserStatType? type,
     bool isMatchComplete = false,
   }) {
-    final newBattingStat = calculateBattingStats(currentUserId);
+    final Batting newBattingStat = calculateBattingStats(currentUserId);
-    final newBowlingStat = calculateBowlingStats(currentUserId);
+    final Bowling newBowlingStat = calculateBowlingStats(currentUserId);
-    final newFieldingStat = calculateFieldingStats(currentUserId);
+    final Fielding newFieldingStat = calculateFieldingStats(currentUserId);

772-779: Simplify filtering conditions by extracting common logic.

The filtering conditions are repeated in multiple places and could be simplified by extracting them into a separate method.

+  bool _isValidDeliveryForStats(BallScoreModel ball) {
+    return (ball.extras_type == null ||
+            ball.extras_type == ExtrasType.legBye ||
+            ball.extras_type == ExtrasType.bye) &&
+           ball.wicket_type != WicketType.retired &&
+           ball.wicket_type != WicketType.retiredHurt &&
+           ball.wicket_type != WicketType.timedOut &&
+           ball.extras_type != ExtrasType.penaltyRun;
+  }

   final bowledBallCountForEconomyRate = deliveries
-      .where(
-        (element) =>
-            (element.extras_type == null ||
-                element.extras_type == ExtrasType.legBye ||
-                element.extras_type == ExtrasType.bye) &&
-                element.wicket_type != WicketType.retired &&
-                element.wicket_type != WicketType.retiredHurt &&
-                element.wicket_type != WicketType.timedOut &&
-                element.extras_type != ExtrasType.penaltyRun,
-      )
+      .where(_isValidDeliveryForStats)
       .length;

819-841: Add documentation explaining maiden over rules.

The method implements the maiden over calculation correctly, but adding documentation would help future maintainers understand the cricket-specific rules.

+  /// Calculates the number of maiden overs bowled.
+  /// 
+  /// A maiden over in cricket is when no runs are scored off the bat
+  /// and no extras are conceded in a complete over of 6 legal deliveries.
   int _calculateMaidenOvers(Iterable<BallScoreModel> deliveries) {

Line range hint 844-869: Add type annotations for better readability.

The method implementation is correct, but adding explicit type annotations would improve code readability.

   Fielding calculateFieldingStats(String currentUserId) {
-    final catches = where(
+    final int catches = where(
       (element) =>
           element.wicket_taker_id == currentUserId &&
           (element.wicket_type == WicketType.caught ||
               element.wicket_type == WicketType.caughtBehind ||
               element.wicket_type == WicketType.caughtAndBowled),
     ).length;

-    final runOuts = where(
+    final int runOuts = where(
       (element) =>
           element.wicket_taker_id == currentUserId &&
           element.wicket_type == WicketType.runOut,
     ).length;

-    final stumpings = where(
+    final int stumpings = where(
       (element) =>
           element.wicket_taker_id == currentUserId &&
           element.wicket_type == WicketType.stumped,
     ).length;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 4cd3df3 and e6fd172.

📒 Files selected for processing (1)
  • data/lib/api/ball_score/ball_score_model.dart (5 hunks)

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 (3)
data/lib/api/ball_score/ball_score_model.dart (3)

639-657: Add documentation for the calculateUserStats method.

Consider adding documentation to explain the purpose of each parameter and the method's behavior, especially the update mechanism when oldUserStats is provided.

+  /// Calculates user statistics for cricket performance.
+  /// 
+  /// Parameters:
+  /// - currentUserId: The ID of the user whose stats are being calculated
+  /// - oldUserStats: Optional existing stats to update
+  /// - type: Optional type of the statistics (e.g., T20, ODI)
+  /// - isMatchComplete: Whether the match is complete, affects matches count
+  /// 
+  /// Returns a new or updated UserStat instance.
   UserStat calculateUserStats(
     String currentUserId, {
     UserStat? oldUserStats,

817-839: Optimize maiden over calculation.

The current implementation can be made more efficient by:

  1. Early exit when ball count isn't 6
  2. Using any() instead of a flag variable for extras
   int _calculateMaidenOvers(Iterable<BallScoreModel> deliveries) {
     final overGroups = groupBy(deliveries, (ball) => ball.over_number);
     int maiden = 0;
     overGroups.forEach((overNumber, balls) {
+      if (balls.length != 6) return;
       int runsConceded = 0;
-      bool hasExtras = false;
+      final hasExtras = balls.any((ball) => ball.extras_type != null);
+      if (hasExtras) return;
       for (final ball in balls) {
         runsConceded += ball.runs_scored + (ball.extras_awarded ?? 0);
-        if (ball.extras_type != null) {
-          hasExtras = true;
-          break;
-        }
       }
-      if (runsConceded == 0 && !hasExtras && balls.length == 6) {
+      if (runsConceded == 0) {
         maiden++;
       }
     });
     return maiden;
   }

Line range hint 842-867: Optimize fielding statistics calculation.

Consider combining similar where clauses to reduce code duplication and improve maintainability.

   Fielding calculateFieldingStats(String currentUserId) {
-    final catches = where(
+    final dismissals = where(
       (element) =>
-          element.wicket_taker_id == currentUserId &&
-          (element.wicket_type == WicketType.caught ||
-              element.wicket_type == WicketType.caughtBehind ||
-              element.wicket_type == WicketType.caughtAndBowled),
-    ).length;
-
-    final runOuts = where(
-      (element) =>
-          element.wicket_taker_id == currentUserId &&
-          element.wicket_type == WicketType.runOut,
-    ).length;
-
-    final stumpings = where(
-      (element) =>
-          element.wicket_taker_id == currentUserId &&
-          element.wicket_type == WicketType.stumped,
-    ).length;
+          element.wicket_taker_id == currentUserId
+    ).toList();
+
+    final catches = dismissals.where((element) =>
+        element.wicket_type == WicketType.caught ||
+        element.wicket_type == WicketType.caughtBehind ||
+        element.wicket_type == WicketType.caughtAndBowled).length;
+
+    final runOuts = dismissals.where((element) =>
+        element.wicket_type == WicketType.runOut).length;
+
+    final stumpings = dismissals.where((element) =>
+        element.wicket_type == WicketType.stumped).length;

     return Fielding(
       catches: catches,
       runOut: runOuts,
       stumping: stumpings,
     );
   }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between e6fd172 and 74eb134.

📒 Files selected for processing (1)
  • data/lib/api/ball_score/ball_score_model.dart (6 hunks)
🔇 Additional comments (2)
data/lib/api/ball_score/ball_score_model.dart (2)

725-725: ⚠️ Potential issue

Fix duck calculation logic.

A duck in cricket occurs only when a batsman is dismissed without scoring any runs (0 runs). The current implementation incorrectly considers scores between 0 and 2 as ducks.

-      if (isDismissed && inningRunScored >= 0 && inningRunScored <= 2) {
+      if (isDismissed && inningRunScored == 0) {

761-764: ⚠️ Potential issue

Revise ball count logic for economy rate.

The current implementation includes penalty runs in the ball count, which is incorrect as these don't count as actual deliveries.

-              element.extras_type != ExtrasType.penaltyRun &&
               element.wicket_type != WicketType.retired &&
               element.wicket_type != WicketType.retiredHurt &&
               element.wicket_type != WicketType.timedOut,

Likely invalid or redundant comment.

@canopas canopas deleted a comment from coderabbitai bot Nov 27, 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: 1

🧹 Outside diff range and nitpick comments (4)
data/lib/api/ball_score/ball_score_model.dart (4)

639-657: Consider enhancing null-safety.

The method handles null cases well but could be more explicit about nullability:

-  UserStat calculateUserStats(
+  UserStat calculateUserStats(
   String currentUserId, {
   UserStat? oldUserStats,
   UserStatType? type,
   bool isMatchComplete = false,
-}) {
+}) {
+  if (currentUserId.isEmpty) {
+    throw ArgumentError('currentUserId cannot be empty');
+  }
   final newBattingStat = calculateBattingStats(currentUserId);
   // ... rest of the method

Line range hint 751-822: Extract common filtering conditions.

The method has duplicate conditions across multiple where clauses. Consider extracting these into named predicates for better maintainability and readability.

+ bool _isValidDelivery(BallScoreModel ball) =>
+   ball.wicket_type != WicketType.retired &&
+   ball.wicket_type != WicketType.retiredHurt &&
+   ball.wicket_type != WicketType.timedOut &&
+   ball.extras_type != ExtrasType.penaltyRun;

  Bowling calculateBowlingStats(String currentUserId) {
    final deliveries = where((element) => element.bowler_id == currentUserId);

    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) => element.wicket_type != null && _isValidDelivery(element),
        )
        .length;
    // ... rest of the method

Line range hint 849-874: Improve readability with named predicates.

The method uses multiple where clauses with similar conditions. Consider extracting these into named predicates for better readability.

+ bool _isCatch(BallScoreModel ball) =>
+   ball.wicket_type == WicketType.caught ||
+   ball.wicket_type == WicketType.caughtBehind ||
+   ball.wicket_type == WicketType.caughtAndBowled;

  Fielding calculateFieldingStats(String currentUserId) {
    final catches = where(
-     (element) =>
-         element.wicket_taker_id == currentUserId &&
-         (element.wicket_type == WicketType.caught ||
-          element.wicket_type == WicketType.caughtBehind ||
-          element.wicket_type == WicketType.caughtAndBowled),
+     (element) => element.wicket_taker_id == currentUserId && _isCatch(element),
    ).length;
    // ... rest of the method

Duck calculation logic needs correction

The current implementation considers a duck when a player is dismissed after facing 0-2 balls, which is incorrect according to cricket rules. A duck occurs when a batsman is dismissed without scoring any runs. The number of balls faced is not relevant for determining a duck.

Let's verify if there are any runs scored in the innings:

- if (isDismissed && inningBallFaced >= 0 && inningBallFaced <= 2) {
+ if (isDismissed && inningRunScored == 0) {
    ducks++;
  }
🔗 Analysis chain

Line range hint 660-748: Verify duck calculation logic and consider method extraction.

  1. The duck calculation logic at line 736 might need verification. In cricket, a duck typically means getting out for zero runs, but the current implementation checks for 0-2 balls faced.

  2. The method is quite long and handles multiple responsibilities. Consider extracting the innings analysis into a separate method.

Consider extracting the innings analysis:

+ Batting _analyzeInnings(Map<String, List<BallScoreModel>> inningGroup, String currentUserId) {
+   int ducks = 0, fifties = 0, hundreds = 0;
+   // ... move innings analysis logic here
+   return Batting(ducks: ducks, fifties: fifties, hundreds: hundreds);
+ }
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other duck implementations in the codebase
rg -A 5 "duck|Duck" --type dart

Length of output: 10665

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 74eb134 and 5ae4c1b.

📒 Files selected for processing (1)
  • data/lib/api/ball_score/ball_score_model.dart (5 hunks)

@canopas canopas deleted a comment from coderabbitai bot Nov 27, 2024
@cp-mayank cp-mayank merged commit 1bf099e into main Nov 27, 2024
2 checks passed
@cp-mayank cp-mayank deleted the Mayank/store-user-stats branch November 27, 2024 10:56
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