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

Refactor tournament detail stats filter #130

Merged
merged 4 commits into from
Nov 7, 2024

Conversation

cp-mayank
Copy link
Collaborator

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

  • Refactor tournament detail stats filter
  • Modify teamStat filter logic and make common extension
refactor_filter.webm

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new extension for team statistics, allowing users to view comprehensive performance metrics for specific teams across matches.
    • Added new filter options for tournament statistics, enhancing user experience in data analysis.
  • Bug Fixes

    • Resolved issues with the sorting of key statistics, ensuring accurate display in the user interface.
  • Improvements

    • Simplified the calculation of team statistics, improving performance and maintainability.
    • Enhanced filtering mechanism for tournament statistics, providing clearer options for users.
  • UI Enhancements

    • Updated the display of key statistics to reflect sorted order, improving readability and user engagement.
    • Replaced the pitch type and wicket type selection UI components with a new design for better user interaction.

Copy link

coderabbitai bot commented Nov 6, 2024

Walkthrough

The changes in this pull request introduce a new extension TeamStatExtension on List<MatchModel> for calculating team statistics across multiple matches. Modifications are made to the TournamentService class by removing sorting from the keyStats list. The localization file is updated with new keys for tournament statistics, while the TeamDetailViewNotifier class is refactored to simplify team statistics calculations. Additional updates include enhancements to filtering mechanisms in the TournamentDetailStatsTab and TournamentDetailStateViewNotifier, improving overall functionality and user interface.

Changes

File Path Change Summary
data/lib/api/match/match_model.dart - Added extension: TeamStatExtension on List<MatchModel>
- Added method: TeamStat teamStat(String teamId)
data/lib/service/tournament/tournament_service.dart - Removed sorting operation on keyStats list
- No changes to method signatures or error handling
khelo/assets/locales/app_en.arb - Added new keys for tournament statistics: key_stat_filter_runs, key_stat_filter_wickets, etc.
- No changes to existing keys or values
khelo/lib/ui/flow/team/detail/team_detail_view_model.dart - Refactored _calculateTeamStat to use teamStat method
- Removed multiple helper methods for calculating statistics
khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_overview_tab.dart - Introduced keyStatsList for sorted key statistics
- Updated _keyStatsView and GridView.builder to reflect sorted order
khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_stats_tab.dart - Updated onFiltered callback parameter type from KeyStatTag to KeyStatFilterTag
- Modified showFilterOptionSelectionSheet method for new filtering logic
khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.dart - Updated onStatFilter method's parameter type to KeyStatFilterTag
- Streamlined _calculatePointsTable method and removed team statistics calculation logic
khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.freezed.dart - Renamed statFilter to selectedFilterTag and updated its type from KeyStatTag to KeyStatFilterTag
- Adjusted multiple methods to reflect the new property name and type
khelo/lib/ui/flow/matches/add_match/components/pitch_selection_view.dart - Replaced custom pitch type selection UI with ChipButton widget, simplifying the component structure
khelo/lib/ui/flow/score_board/components/select_wicket_type_sheet.dart - Replaced OnTapScale widget with ChipButton for selecting wicket types, updating visual representation
style/lib/button/chip_button.dart - Introduced ChipButton class for selectable chip buttons, encapsulating button behavior and appearance

Possibly related PRs

  • Team initials while adding team #108: Introduces a new field for team initials in the TeamModel, which could relate to the team statistics being calculated in the main PR, enhancing the representation of teams.
  • Add team in tournament #120: Adds team selection functionality within tournaments, which could relate to the team statistics being calculated in the main PR, enhancing the representation of teams.
  • Implement tournament matches tab #123: Implements a tournament detail stats tab, directly relating to the statistical analysis of teams and players, making it highly relevant to the main PR.
  • Implement tournament detail stats tab #124: Implements a tournament points table tab, directly related to the statistical representation of teams and their performance, making it relevant to the main PR.
  • Implement tournament points table tab #125: Introduces a tournament points table, directly related to the statistical analysis of teams and their performance, making it relevant to the main PR.

Suggested reviewers

  • cp-sidhdhi-p

🐇 "In the fields where matches play,
Stats and scores now find their way.
With extensions new and filters bright,
Team performances take flight!
A hop, a skip, to stats we cheer,
For cricket's glory, we hold dear!" 🎉


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between fc6ec28 and 2ac1a46.

📒 Files selected for processing (1)
  • data/lib/api/match/match_model.dart (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • data/lib/api/match/match_model.dart

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: 3

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

Line range hint 134-147: Consider optimizing the getKeyStats method for better performance and maintainability.

The method currently handles multiple responsibilities and uses nested loops which could impact performance with large datasets. Consider these improvements:

  1. Split the method into smaller, focused functions
  2. Use more efficient data structures to reduce loop complexity
  3. Add specific error handling for score calculations

Here's a suggested refactoring:

 Future<List<PlayerKeyStat>> getKeyStats(List<MatchModel> matches) async {
+  try {
+    final scores = await _fetchBallScores(matches);
+    final playerStats = _calculatePlayerStats(matches, scores);
+    final keyStats = playerStats.getTopKeyStats();
+    return _filterActivePlayers(keyStats);
+  } catch (error, stack) {
+    throw AppError.fromError(error, stack);
+  }
 }

+Future<List<BallScore>> _fetchBallScores(List<MatchModel> matches) async {
+  final matchIds = matches.map((match) => match.id).toList();
+  return _ballScoreService.getBallScoresByMatchIds(matchIds);
+}

+List<PlayerKeyStat> _calculatePlayerStats(
+  List<MatchModel> matches,
+  List<BallScore> scores,
+) {
+  return matches.expand((match) {
+    return match.teams.expand((team) {
+      return team.squad.map((player) {
+        final stats = scores.calculateUserStats(player.id);
+        return PlayerKeyStat(
+          player: player.player,
+          teamName: team.team.name,
+          stats: stats,
+        );
+      });
+    });
+  }).toList();
+}

+List<PlayerKeyStat> _filterActivePlayers(List<PlayerKeyStat> stats) {
+  return stats.where((element) => element.player.isActive).toList();
+}
khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_stats_tab.dart (1)

225-243: Enhance accessibility for filter chips

The filter chips should include semantic labels for better accessibility.

Wrap the Chip widget with a Semantics widget:

-  child: Chip(
+  child: Semantics(
+    selected: isSelected,
+    value: 'Filter by ${element.getString(context)}',
+    child: Chip(
data/lib/api/match/match_model.dart (1)

428-439: Add documentation and optimize run rate calculation.

Helper methods lack documentation explaining their purpose and assumptions. Also, run rate calculation requires an additional iteration over the list.

Add documentation and optimize the code:

+ /// Returns the team model for the specified team ID from a match
+ /// Throws [StateError] if team is not found
  MatchTeamModel _getTeam(MatchModel match, String teamId) =>
      match.teams.firstWhere((team) => team.team.id == teamId);

+ /// Returns the opponent team model for the specified team ID from a match
+ /// Throws [StateError] if team is not found
  MatchTeamModel _getOpponentTeam(MatchModel match, String teamId) =>
      match.teams.firstWhere((team) => team.team.id != teamId);

  double _runRate(String teamId, int runs) {
-    final totalOvers = map((match) => _getTeam(match, teamId))
-        .fold<double>(0.0, (total, team) => total + team.over);
-
-    return totalOvers > 0 ? runs / totalOvers : 0;
+    // Calculate total overs during the main iteration in teamStat method
+    double totalOvers = 0.0;
+    for (final match in this) {
+      totalOvers += _getTeam(match, teamId).over;
+    }
+    return totalOvers > 0 ? runs / totalOvers : 0;
  }
khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_overview_tab.dart (2)

153-154: Consider simplifying the sort comparison.

The sort implementation can be made more concise while maintaining null safety.

-    final keyStatsList = List.of(keyStats)
-      ..sort((a, b) => b.value?.compareTo(a.value ?? 0) ?? 0);
+    final keyStatsList = List.of(keyStats)
+      ..sort((a, b) => (b.value ?? 0).compareTo(a.value ?? 0));

171-171: Consider caching the truncated list length.

To avoid recomputing take(4).length on every build, consider storing it in a variable.

     final keyStatsList = List.of(keyStats)
       ..sort((a, b) => (b.value ?? 0).compareTo(a.value ?? 0));
+    final displayCount = keyStatsList.take(4).length;
 
     return Padding(
       // ...
           GridView.builder(
             shrinkWrap: true,
             physics: NeverScrollableScrollPhysics(),
-            itemCount: keyStatsList.take(4).length,
+            itemCount: displayCount,

Also applies to: 180-180

khelo/assets/locales/app_en.arb (2)

243-249: LGTM! Consider adding pluralization support.

The new filter keys follow the existing naming convention and integrate well with the refactored tournament detail stats filter. However, consider adding pluralization support for these statistics, similar to how it's implemented for other count-based strings in the file.

Example implementation:

-  "key_stat_filter_runs": "Runs",
+  "key_stat_filter_runs": "{count, plural, =0{No runs} =1{Run} other{Runs}}",
+  "@key_stat_filter_runs": {
+    "placeholders": {
+      "count": {}
+    }
+  },

243-249: Add descriptions for translation context.

To help translators better understand the context and usage of these new filter keys, consider adding description metadata.

Example implementation:

   "key_stat_filter_runs": "Runs",
+  "@key_stat_filter_runs": {
+    "description": "Filter option for viewing runs statistics in tournament details"
+  },
khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.dart (2)

125-129: Consider sorting the filtered stats by runs scored.

Currently, the filtered list for KeyStatFilterTag.runs is not sorted. Sorting the players by the number of runs scored will display the top performers first and enhance the user experience.

Apply this diff to sort the filtered stats:

filteredStats = filteredStats
     .where((element) => (element.stats.battingStat?.runScored ?? 0) > 0)
+    ..sort((a, b) => (b.stats.battingStat?.runScored ?? 0)
+        .compareTo(a.stats.battingStat?.runScored ?? 0))
     .toList();

130-135: Consider sorting the filtered stats by wickets taken.

Similarly, sorting the players by the number of wickets taken in the KeyStatFilterTag.wickets case will highlight leading bowlers and improve data presentation.

Apply this diff to sort the filtered stats:

filteredStats = filteredStats
     .where((element) => (element.stats.bowlingStat?.wicketTaken ?? 0.0) > 0.0)
+    ..sort((a, b) => (b.stats.bowlingStat?.wicketTaken ?? 0.0)
+        .compareTo(a.stats.bowlingStat?.wicketTaken ?? 0.0))
     .toList();
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between bdd2d09 and 78699f1.

📒 Files selected for processing (8)
  • data/lib/api/match/match_model.dart (1 hunks)
  • data/lib/service/tournament/tournament_service.dart (1 hunks)
  • khelo/assets/locales/app_en.arb (1 hunks)
  • khelo/lib/ui/flow/team/detail/team_detail_view_model.dart (1 hunks)
  • khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_overview_tab.dart (2 hunks)
  • khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_stats_tab.dart (3 hunks)
  • khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.dart (3 hunks)
  • khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.freezed.dart (14 hunks)
🔇 Additional comments (13)
data/lib/service/tournament/tournament_service.dart (1)

144-144: Verify the sorting behavior in getTopKeyStats extension.

The sorting logic has been moved from this method to the getTopKeyStats() extension method. While this improves code organization, we should ensure that the extension method maintains the expected sorting behavior.

Let's verify the implementation and usage:

✅ Verification successful

The sorting logic removal is correct and safe

After reviewing the complete implementation, I can confirm that the removal of sorting from the original method is correct. The getTopKeyStats() extension method doesn't need explicit sorting because:

  1. It maintains a map (playerMap) that tracks the highest stats for each player
  2. For each player, it tracks their best performance across runs, wickets, fours, and sixes
  3. When a player has multiple stats, it only keeps the highest value through the comparison highestValue > (existingPlayerStat.value ?? 0)
  4. The final list returned by playerMap.values.toList() contains only the top performers for each category

The implementation ensures that each player appears only once with their best statistical achievement, making additional sorting unnecessary.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check the implementation of getTopKeyStats extension and its usage

# Test 1: Find the extension implementation
echo "Looking for getTopKeyStats extension implementation..."
rg "getTopKeyStats" -A 10

# Test 2: Find other usages of getTopKeyStats to ensure consistent behavior
echo "Looking for other usages of getTopKeyStats..."
rg "\.getTopKeyStats\(\)"

# Test 3: Look for any sorting-related tests
echo "Looking for related test files..."
fd -e dart -e test "tournament.*test|stat.*test"

Length of output: 2232


Script:

#!/bin/bash
# Let's examine the complete implementation of PlayerKeyStat and related sorting logic

# Look for PlayerKeyStat class definition and implementation
echo "Looking for PlayerKeyStat class..."
ast-grep --pattern 'class PlayerKeyStat {
  $$$
}'

# Check for any sorting or comparison logic in the model
echo "Looking for sorting/comparison implementations..."
rg "compareTo|sort" data/lib/api/tournament/tournament_model.dart -A 5

# Get more context around getTopKeyStats implementation
echo "Getting full context of getTopKeyStats..."
rg "getTopKeyStats" data/lib/api/tournament/tournament_model.dart -B 5 -A 20

Length of output: 1253


Script:

#!/bin/bash
# Let's get the complete implementation of getTopKeyStats and any related tests

# Get the complete file content to see the full implementation
echo "Getting complete tournament model file..."
cat data/lib/api/tournament/tournament_model.dart

# Look for any test files that might verify the sorting behavior
echo "Looking for tournament model tests..."
fd -e dart "tournament_model_test|tournament_service_test"

# Check for any usage of KeyStatTag enum
echo "Looking for KeyStatTag definition and usage..."
rg "KeyStatTag" -A 5

Length of output: 14884

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

19-19: LGTM: Type change improves clarity

The callback type change from KeyStatTag to KeyStatFilterTag provides better type safety and clearer intent for the filtering mechanism.


46-49: LGTM: Consistent naming improvements

The parameter updates from statFilter to selectedFilterTag improve code readability and maintain consistency with the new filtering mechanism.


201-250: 🛠️ Refactor suggestion

Add haptic feedback for filter selection

The bottom sheet implementation looks good, but as mentioned in the previous review, we should add haptic feedback for the filter selection.

Add this before context.pop():

   onTap: () {
+    HapticFeedback.mediumImpact();
     context.pop();
     onTap(element);
   },
data/lib/api/match/match_model.dart (1)

344-348: Consider using BigInt for runs accumulation.

For tournaments with many matches, integer overflow could occur when accumulating runs. Consider using BigInt for the accumulation and converting back to int for the final result.

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

163-163: LGTM!

Consistently using keyStatsList for the view all condition.

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

Line range hint 1-4: LGTM: Generated code maintains consistency.

The generated code correctly implements all the necessary Freezed functionality for the updated property.


252-252: Verify the default value change impact.

The default value is now set to KeyStatFilterTag.runs. This change in default behavior could affect existing functionality.

#!/bin/bash
# Description: Find all direct instantiations of TournamentDetailState to verify default value usage
echo "Searching for TournamentDetailState instantiations..."
rg "TournamentDetailState\(" --type dart

27-27: Verify the impact of KeyStatTag to KeyStatFilterTag migration.

The type change from KeyStatTag to KeyStatFilterTag for the renamed property selectedFilterTag (previously statFilter) is a breaking change that could affect dependent code. Let's verify all usages to ensure proper migration.

Also applies to: 53-53, 84-84, 115-118, 163-163, 193-193, 224-227, 252-252, 288-288, 309-309, 331-332, 350-350, 374-374, 395-395

✅ Verification successful

Let's analyze the search results. The output shows:

  1. No occurrences of KeyStatTag found, suggesting complete removal
  2. All KeyStatFilterTag usages are properly contained within the tournament detail feature files:
    • tournament_detail_view_model.freezed.dart (generated)
    • tournament_detail_view_model.dart (source)
    • tournament_detail_stats_tab.dart (UI)
  3. No old statFilter usages found

Let's verify if there are any imports of KeyStatTag that might need cleanup:


Migration from KeyStatTag to KeyStatFilterTag is complete and consistent

The verification shows that:

  1. No traces of the old KeyStatTag enum exist in the codebase
  2. The new KeyStatFilterTag is properly scoped within the tournament detail feature
  3. All related files (view model, generated code, and UI) have been updated consistently
  4. No test files are affected by this change
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all usages of both KeyStatTag and KeyStatFilterTag to ensure complete migration
echo "Searching for old KeyStatTag usages that might need updating..."
rg "KeyStatTag" --type dart

echo -e "\nSearching for new KeyStatFilterTag usages..."
rg "KeyStatFilterTag" --type dart

echo -e "\nSearching for old statFilter usages that might need updating..."
rg "statFilter" --type dart

Length of output: 5176


Script:

#!/bin/bash
# Search for potential import statements of KeyStatTag
rg "import.*KeyStatTag" --type dart

# Also check for any potential references in test files
rg "KeyStatTag" --type dart --glob "**/*test*.dart"

Length of output: 89

khelo/lib/ui/flow/team/detail/team_detail_view_model.dart (1)

61-64: Simplified team statistics calculation enhances maintainability

The refactored _calculateTeamStat method now efficiently computes team statistics by utilizing the teamStat extension method on the filtered list of finished matches. This change eliminates the need for multiple helper methods, improving both readability and maintainability of the code.

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

11-11: Approved addition of necessary import.

The import of context_extensions.dart is required for localization and context extensions used in the code.


197-199: Approved the streamlined retrieval of finished matches.

Filtering finished matches directly from the tournament's matches improves readability and efficiency.


207-207: Confirmed usage of the teamStat extension method.

Utilizing matches.teamStat(team.id) simplifies the calculation of team statistics and aligns with the refactored logic introduced in the codebase.

data/lib/api/match/match_model.dart Show resolved Hide resolved
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: 4

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

Line range hint 119-146: Consider optimizing the statistics calculation process.

The current implementation of getKeyStats processes all matches and players sequentially. As part of the refactoring effort, consider these improvements:

  1. Batch processing of ball scores to reduce database calls
  2. Parallel processing for large datasets
  3. Caching frequently accessed statistics

Example optimization:

Future<List<PlayerKeyStat>> getKeyStats(List<MatchModel> matches) async {
  // Batch fetch all scores at once
  final matchIds = matches.map((match) => match.id).toSet().toList();
  final scores = await _ballScoreService.getBallScoresByMatchIds(matchIds);
  
  // Process statistics in parallel for better performance
  final playerStats = await Future.wait(
    matches.expand((match) => match.teams.expand((team) => 
      team.squad.map((player) => 
        PlayerKeyStat(
          player: player.player,
          teamName: team.team.name,
          stats: scores.calculateUserStats(player.id),
        )
      )
    )).toList()
  );

  return playerStats
    .getTopKeyStats()
    .where((element) => element.player.isActive)
    .toList();
}
khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_stats_tab.dart (1)

198-250: Consider refactoring for better maintainability.

The new filter sheet implementation is a good improvement with better UX, but there are some opportunities for enhancement:

  1. Simplify padding composition
  2. Extract color management to reduce duplication
  3. Consider moving chip styling to a theme or constant
  4. Break down the method into smaller, more focused methods

Here's a suggested refactoring:

+ // Extract to a separate widget
+ class FilterOptionChip extends StatelessWidget {
+   final KeyStatFilterTag tag;
+   final KeyStatFilterTag? selectedTag;
+   final ValueChanged<KeyStatFilterTag> onTap;
+
+   const FilterOptionChip({
+     required this.tag,
+     required this.selectedTag,
+     required this.onTap,
+   });
+
+   @override
+   Widget build(BuildContext context) {
+     final isSelected = selectedTag == tag;
+     return OnTapScale(
+       onTap: () {
+         context.pop();
+         onTap(tag);
+       },
+       child: Chip(
+         label: Text(
+           tag.getString(context),
+           style: AppTextStyle.body2.copyWith(
+             color: isSelected
+                 ? context.colorScheme.onPrimary
+                 : context.colorScheme.textSecondary,
+           ),
+         ),
+         padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
+         side: const BorderSide(color: Colors.transparent),
+         shape: RoundedRectangleBorder(
+           borderRadius: BorderRadius.circular(30),
+         ),
+         backgroundColor: isSelected
+             ? context.colorScheme.primary
+             : context.colorScheme.containerLowOnSurface,
+       ),
+     );
+   }
+ }

  void showFilterOptionSelectionSheet(
    BuildContext context, {
    required Function(KeyStatFilterTag) onTap,
    KeyStatFilterTag? selectedTag,
  }) async {
    return await showModalBottomSheet(
      context: context,
      showDragHandle: true,
      enableDrag: true,
      isScrollControlled: true,
      useRootNavigator: true,
      backgroundColor: context.colorScheme.surface,
      builder: (context) {
        return Container(
          width: double.infinity,
-         padding: EdgeInsets.all(16)
-             .copyWith(bottom: context.mediaQueryPadding.bottom + 24),
+         padding: EdgeInsets.fromLTRB(16, 16, 16, context.mediaQueryPadding.bottom + 24),
          child: Wrap(
            alignment: WrapAlignment.start,
            spacing: 8,
            runSpacing: 8,
            children: KeyStatFilterTag.values.map(
-             (element) {
-               final isSelected = selectedTag == element;
-               return OnTapScale(
-                 onTap: () {
-                   context.pop();
-                   onTap(element);
-                 },
-                 child: Chip(
-                   label: Text(
-                     element.getString(context),
-                     style: AppTextStyle.body2.copyWith(
-                       color: isSelected
-                           ? context.colorScheme.onPrimary
-                           : context.colorScheme.textSecondary,
-                     ),
-                   ),
-                   padding:
-                       const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
-                   side: const BorderSide(color: Colors.transparent),
-                   shape: RoundedRectangleBorder(
-                     borderRadius: BorderRadius.circular(30),
-                   ),
-                   backgroundColor: isSelected
-                       ? context.colorScheme.primary
-                       : context.colorScheme.containerLowOnSurface,
-                 ),
-               );
-             },
+             (tag) => FilterOptionChip(
+               tag: tag,
+               selectedTag: selectedTag,
+               onTap: onTap,
+             ),
            ).toList(),
          ),
        );
      },
    );
  }
data/lib/api/match/match_model.dart (3)

340-381: Add documentation for complex statistical calculations.

The teamStat method performs complex cricket statistics calculations. Adding documentation would help maintainers understand the business logic and formulas used.

Add documentation like this:

+ /// Calculates comprehensive statistics for a team across multiple matches.
+ /// 
+ /// Parameters:
+ /// - teamId: The ID of the team to calculate statistics for
+ /// 
+ /// Returns a TeamStat object containing:
+ /// - Batting average = Total runs / Total wickets lost
+ /// - Bowling average = Total runs conceded / Total wickets taken
+ /// - Run rate = Total runs / Total overs
+ /// - Match status (wins/losses/ties)
+ /// - Highest and lowest team scores
  TeamStat teamStat(String teamId) {

383-426: Refactor match status calculation for better readability.

The current implementation has deep nesting and complex logic that makes it hard to maintain. Consider:

  1. Extracting the winner determination logic
  2. Handling abandoned matches
  3. Simplifying the nested conditions

Consider this refactor:

  TeamMatchStatus _teamMatchStatus(String teamId) {
    return fold<TeamMatchStatus>(
      const TeamMatchStatus(),
      (status, match) {
+       // Skip abandoned matches
+       if (match.match_status == MatchStatus.abandoned) {
+         return status;
+       }
+
+       final winner = _determineMatchWinner(match);
+       if (winner.isTie) {
          return TeamMatchStatus(
            win: status.win,
            lost: status.lost,
            tie: status.tie + 1,
          );
+       } else if (winner.teamId == teamId) {
          return TeamMatchStatus(
            win: status.win + 1,
            lost: status.lost,
            tie: status.tie,
          );
        } else {
          return TeamMatchStatus(
            win: status.win,
            lost: status.lost + 1,
            tie: status.tie,
          );
        }
      },
    );
  }

+ /// Determines the winner of a match
+ /// Returns a MatchWinner object containing the winning team's ID
+ /// or indicates a tie
+ MatchWinner _determineMatchWinner(MatchModel match) {
+   final firstTeam = match.teams.firstWhere(
+     (team) => team.team.id == (
+       match.toss_decision == TossDecision.bat
+         ? match.toss_winner_id
+         : match.teams
+             .firstWhere((team) => team.team.id != match.toss_winner_id)
+             .team
+             .id
+     ),
+   );
+
+   final secondTeam = match.teams.firstWhere(
+     (team) => team.team.id != firstTeam.team.id
+   );
+
+   if (firstTeam.run == secondTeam.run) {
+     return MatchWinner.tie();
+   }
+
+   return MatchWinner(
+     teamId: firstTeam.run > secondTeam.run 
+       ? firstTeam.team.id 
+       : secondTeam.team.id
+   );
+ }

434-439: Optimize run rate calculation.

The current implementation makes multiple passes over the match list. Consider combining the runs and overs calculation in a single pass.

  double _runRate(String teamId, int runs) {
-   final totalOvers = map((match) => _getTeam(match, teamId))
-       .fold<double>(0.0, (total, team) => total + team.over);
-
-   return totalOvers > 0 ? runs / totalOvers : 0;
+   final totalOvers = fold<double>(
+     0.0,
+     (total, match) => total + _getTeam(match, teamId).over
+   );
+   
+   return totalOvers > 0 ? runs / totalOvers : 0;
  }
khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_overview_tab.dart (2)

163-163: Optimize length check for view all button.

The length check could be done on the original list since sorting doesn't affect the length.

-showViewAll: keyStatsList.length > 4,
+showViewAll: keyStats.length > 4,

171-171: Optimize list operations in GridView.builder.

The current implementation creates unnecessary temporary lists and may perform redundant index access operations.

Consider these optimizations:

-itemCount: keyStatsList.take(4).length,
+itemCount: keyStatsList.length.clamp(0, 4),

-_keyStatsCellView(context, keyStatsList[index]),
+_keyStatsCellView(context, keyStatsList[index.clamp(0, 3)]),

This approach:

  1. Avoids creating a temporary list with take(4)
  2. Ensures safe index access with clamp
  3. Improves performance by reducing object allocations

Also applies to: 180-180

khelo/assets/locales/app_en.arb (1)

243-251: LGTM! Consider adding pluralization support.

The new filter keys are well-organized and follow consistent naming conventions. However, for better internationalization support, consider adding pluralization rules for numerical statistics, similar to how it's implemented in other keys like common_runs_title.

Example implementation for runs:

-  "key_stat_filter_runs": "Runs",
+  "key_stat_filter_runs": "{count, plural, =0{Runs} =1{Run} other{Runs}}",
+  "@key_stat_filter_runs": {
+    "placeholders": {
+      "count": {}
+    }
+  },
khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.dart (2)

119-191: Refactor onStatFilter method to reduce code duplication

The onStatFilter method contains repetitive code across multiple switch cases for filtering filteredStats. Refactoring this method can enhance maintainability and readability.

Consider mapping each KeyStatFilterTag to its corresponding filter logic:

void onStatFilter(KeyStatFilterTag? tag) {
  if (state.tournament == null) return;

  var filteredStats = state.tournament!.keyStats;

  final filterMap = {
    KeyStatFilterTag.runs: (PlayerKeyStat e) => (e.stats.battingStat?.runScored ?? 0) > 0,
    KeyStatFilterTag.wickets: (PlayerKeyStat e) => (e.stats.bowlingStat?.wicketTaken ?? 0.0) > 0.0,
    KeyStatFilterTag.battingAverage: (PlayerKeyStat e) => (e.stats.battingStat?.average ?? 0.0) > 0.0,
    KeyStatFilterTag.bowlingAverage: (PlayerKeyStat e) => (e.stats.bowlingStat?.average ?? 0.0) > 0.0,
    // Add other filters as needed
  };

  if (tag != null && filterMap.containsKey(tag)) {
    filteredStats = filteredStats.where(filterMap[tag]!).toList();
  }

  state = state.copyWith(
    filteredStats: filteredStats,
    selectedFilterTag: tag ?? state.selectedFilterTag,
  );
}

244-277: Avoid using BuildContext within enum KeyStatFilterTag

Embedding BuildContext in the KeyStatFilterTag enum ties it to the Flutter framework, reducing the enum's testability and reusability. Consider moving the localization logic outside the enum.

You can create an extension method for localization:

extension KeyStatFilterTagExtension on KeyStatFilterTag {
  String getString(BuildContext context) {
    switch (this) {
      case KeyStatFilterTag.runs:
        return context.l10n.key_stat_filter_runs;
      case KeyStatFilterTag.wickets:
        return context.l10n.key_stat_filter_wickets;
      // Add other cases
    }
  }
}

This approach keeps the enum pure and separates UI concerns from the data model.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between bdd2d09 and 5ec27fc.

📒 Files selected for processing (8)
  • data/lib/api/match/match_model.dart (1 hunks)
  • data/lib/service/tournament/tournament_service.dart (1 hunks)
  • khelo/assets/locales/app_en.arb (1 hunks)
  • khelo/lib/ui/flow/team/detail/team_detail_view_model.dart (1 hunks)
  • khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_overview_tab.dart (2 hunks)
  • khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_stats_tab.dart (3 hunks)
  • khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.dart (3 hunks)
  • khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.freezed.dart (14 hunks)
🔇 Additional comments (8)
khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_stats_tab.dart (3)

9-9: LGTM! Good UX enhancement.

The addition of on_tap_scale.dart import enhances user interaction feedback with animation effects.


46-49: LGTM! Clean and readable implementation.

The changes to FilterTabView usage are well-structured with clear named parameters and proper state management.


19-19: Verify type change consistency across the codebase.

The parameter type change from KeyStatTag to KeyStatFilterTag looks good, but let's ensure all related code is updated.

data/lib/api/match/match_model.dart (1)

368-368: 🛠️ Refactor suggestion

Add null check for division by zero in bowling average calculation.

The bowling average calculation should handle the case where length is 0 more explicitly.

- final bowlingAverage = length > 0.0 ? bowlingAverageTotal / length : 0.0;
+ final bowlingAverage = length > 0 ? bowlingAverageTotal / length : 0.0;

Likely invalid or redundant comment.

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

163-163: Verify architectural impact of moving sorting logic.

The PR moves sorting from the service layer to the UI layer. Please ensure:

  1. Other views using the same data aren't affected by this change
  2. The unimplemented view all functionality (onViewAll: () {}) has a follow-up task

Also applies to: 171-171, 180-180

✅ Verification successful

Let me analyze the sorting implementation to verify the architectural impact.


Moving sorting to UI layer is architecturally sound

The changes are well-structured and don't impact other views:

  • The service layer still provides keyStats data through getKeyStats() method
  • Sorting is appropriately moved to UI layer since it's view-specific filtering based on user selection (hundreds, fifties, sixes)
  • Other views using keyStats from TournamentModel can implement their own sorting as needed

The view all functionality is implemented through showViewAll prop and list limiting (take(4)), with proper UI handling.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other usages of keyStats that might expect sorted data
rg "keyStats" --type dart

# Search for TODOs related to view all functionality
rg "TODO.*view.*all" --type dart

Length of output: 4464


Script:

#!/bin/bash
# Let's check the implementation details of sorting logic in both service and UI layers
ast-grep --pattern 'getTopKeyStats()' 

# Check for any sorting related code in the tournament detail files
rg "sort" -A 3 --type dart khelo/lib/ui/flow/tournament/detail/

Length of output: 2351

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

27-27: Verify the impact of the enum value change.

The generated code changes look correct and consistent. However, please verify that changing from KeyStatTag.mostRuns to KeyStatFilterTag.runs maintains the same semantic meaning and doesn't break existing functionality.

Let's verify the enum definitions and their usage:

Also applies to: 53-53, 84-84, 115-118, 163-163, 193-193, 224-227, 252-252, 288-288, 309-309, 331-332, 350-350, 374-374, 395-395

✅ Verification successful

Let me gather more context about the relationship between these enums by checking their usage patterns.


Let me check the specific implementations in these files to understand the relationship between these enums.


Based on the code analysis, I can now provide the final response:

The enum change is safe and represents an intentional refactoring.

The change from KeyStatTag to KeyStatFilterTag is a deliberate refactoring where:

  1. KeyStatTag (in data layer) is used for API/data models to represent basic stats (mostRuns, mostWickets, mostFours, mostSixes)
  2. KeyStatFilterTag (in UI layer) is a new, more comprehensive enum for UI filtering with additional options (runs, wickets, battingAverage, bowlingAverage, etc.)

The change from mostRuns to runs is semantically equivalent, as evidenced by the filtering logic in onStatFilter() method which properly handles the runs case by filtering based on battingStat?.runScored.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check the definitions and usage of both enums to ensure compatibility

# Find the enum definitions
echo "=== Enum Definitions ==="
rg -A 5 "enum KeyStatTag|enum KeyStatFilterTag"

# Find usages of both enum values
echo -e "\n=== Enum Value Usage ==="
rg "KeyStatTag\.mostRuns|KeyStatFilterTag\.runs"

Length of output: 1826


Script:

#!/bin/bash
# Check for any mapping or conversion between the two enum types
echo "=== Enum Conversion/Mapping ==="
rg -B 2 -A 2 "KeyStatTag.*KeyStatFilterTag|KeyStatFilterTag.*KeyStatTag"

# Check the full implementation of files where both enums are used
echo -e "\n=== Files Using Both Enums ==="
fd -e dart -x sh -c 'if grep -l "KeyStatTag" {} && grep -l "KeyStatFilterTag" {}; then echo "=== {}:"; cat {}; fi'

Length of output: 546


Script:

#!/bin/bash
# Check the content of key files
echo "=== enum_extensions.dart ==="
cat "khelo/lib/domain/extensions/enum_extensions.dart"

echo -e "\n=== tournament_detail_view_model.dart ==="
cat "khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.dart"

Length of output: 21275

khelo/lib/ui/flow/team/detail/team_detail_view_model.dart (1)

61-64: Refactored team statistics calculation enhances simplicity and maintainability.

The use of the teamStat extension method in _calculateTeamStat simplifies the code by delegating statistical calculations, reducing code duplication, and improving readability.

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

11-11: Import statement added appropriately

The addition of context_extensions.dart is necessary for localization extensions used in the code.

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

🧹 Outside diff range and nitpick comments (10)
style/lib/button/chip_button.dart (3)

1-6: Consider organizing imports following Flutter conventions.

Consider organizing imports into three sections separated by blank lines:

  1. Dart/Flutter SDK imports
  2. Package imports
  3. Local imports
 import 'package:flutter/material.dart';
+
 import 'package:style/extensions/context_extensions.dart';
-
 import '../animations/on_tap_scale.dart';
 import '../text/app_text_style.dart';

7-11: Add documentation for better code maintainability.

Consider adding documentation comments to describe:

  • The widget's purpose and use cases
  • Parameter descriptions
  • Example usage
+/// A selectable chip button widget that changes appearance based on selection state.
+///
+/// Parameters:
+/// - [isSelected]: Controls the visual state of the button
+/// - [title]: The text to display on the chip
+/// - [onTap]: Callback function triggered when the chip is tapped
+///
+/// Example:
+/// ```dart
+/// ChipButton(
+///   isSelected: true,
+///   title: 'Select Me',
+///   onTap: () => print('Chip tapped'),
+/// )
+/// ```
 class ChipButton extends StatelessWidget {
   final bool isSelected;
   final String title;
   final VoidCallback? onTap;

19-42: Consider these improvements for better maintainability and accessibility.

While the implementation is functional, consider these enhancements:

  1. Extract magic numbers into named constants
  2. Add semantic properties for accessibility
  3. Use theme-based text styles instead of direct style modifications
+  static const double _horizontalPadding = 16.0;
+  static const double _verticalPadding = 8.0;
+  static const double _borderRadius = 30.0;

   @override
   Widget build(BuildContext context) {
     return OnTapScale(
       onTap: onTap,
+      child: Semantics(
+        button: true,
+        selected: isSelected,
+        label: '$title chip button',
       child: Chip(
         label: Text(
           title,
-          style: AppTextStyle.body2.copyWith(
-            color: isSelected
-                ? context.colorScheme.onPrimary
-                : context.colorScheme.textSecondary,
-          ),
+          style: Theme.of(context).textTheme.bodyMedium?.copyWith(
+            color: isSelected
+                ? context.colorScheme.onPrimary
+                : context.colorScheme.textSecondary,
+          ),
         ),
-        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
+        padding: const EdgeInsets.symmetric(
+          horizontal: _horizontalPadding,
+          vertical: _verticalPadding
+        ),
         side: const BorderSide(color: Colors.transparent),
         shape: RoundedRectangleBorder(
-          borderRadius: BorderRadius.circular(30),
+          borderRadius: BorderRadius.circular(_borderRadius),
         ),
         backgroundColor: isSelected
             ? context.colorScheme.primary
             : context.colorScheme.containerLowOnSurface,
       ),
+      ),
     );
   }
khelo/lib/ui/flow/score_board/components/select_wicket_type_sheet.dart (1)

66-69: Consider enhancing accessibility for wicket type selection.

The ChipButton implementation is clean and effective. However, consider adding accessibility support for better user experience.

Consider these accessibility enhancements:

 return ChipButton(
   isSelected: isSelected,
   title: element.getString(context),
   onTap: () => setState(() => selectedType = element),
+  semanticsLabel: '${element.getString(context)} wicket type option${isSelected ? ', selected' : ''}',
 );
khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.dart (1)

227-266: LGTM: Well-structured enum with localization support.

The KeyStatFilterTag enum is well-implemented with:

  1. Clear, descriptive names
  2. Proper localization integration
  3. Comprehensive coverage of stat types

Consider adding documentation comments to describe each enum value's purpose and any specific business rules associated with them.

/// Enum representing different types of statistical filters for tournament details.
enum KeyStatFilterTag {
  /// Filter by total runs scored
  runs,
  /// Filter by total wickets taken
  wickets,
  // Add documentation for other values...
}
data/lib/api/match/match_model.dart (2)

383-426: Simplify team selection logic in _teamMatchStatus method.

The team selection logic in the _teamMatchStatus method is deeply nested and could be simplified for better readability.

Consider extracting the team selection logic:

-        final firstTeam = match.teams.firstWhere(
-          (team) =>
-              team.team.id ==
-              (match.toss_decision == TossDecision.bat
-                  ? match.toss_winner_id
-                  : match.teams
-                      .firstWhere(
-                        (team) => team.team.id != match.toss_winner_id,
-                      )
-                      .team
-                      .id),
-        );
+        final firstBattingTeamId = match.toss_decision == TossDecision.bat
+            ? match.toss_winner_id
+            : match.teams
+                .firstWhere((team) => team.team.id != match.toss_winner_id)
+                .team
+                .id;
+        final firstTeam =
+            match.teams.firstWhere((team) => team.team.id == firstBattingTeamId);

434-439: Improve null safety in _runRate calculation.

The _runRate method should handle potential null or invalid over values more robustly.

Consider adding validation:

   double _runRate(String teamId, int runs) {
     final totalOvers = map((match) => _getTeam(match, teamId))
-        .fold<double>(0.0, (total, team) => total + team.over);
+        .fold<double>(0.0, (total, team) => total + (team.over ?? 0.0));
 
-    return totalOvers > 0 ? runs / totalOvers : 0;
+    return totalOvers > 0.0 ? (runs / totalOvers).clamp(0.0, double.infinity) : 0.0;
   }
khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_stats_tab.dart (3)

20-20: Use explicit function type instead of 'Function'

Using the generic Function type can reduce type safety and readability. It's recommended to specify the function type explicitly as void Function(KeyStatFilterTag) to ensure better type checking and clarity.

Apply this diff to enhance type safety:

-  final Function(KeyStatFilterTag) onFiltered;
+  final void Function(KeyStatFilterTag) onFiltered;

199-200: Specify function type explicitly for 'onTap' parameter

For better type safety and readability, replace the generic Function type with an explicit function type void Function(KeyStatFilterTag).

Apply this diff to update the function signature:

   void showFilterOptionSelectionSheet(
     BuildContext context, {
-      required Function(KeyStatFilterTag) onTap,
+      required void Function(KeyStatFilterTag) onTap,
       KeyStatFilterTag? selectedTag,
     }) async {

221-226: Avoid potential confusion with identical parameter and local variable names

Using onTap as both a parameter name and a local variable within the callback can lead to confusion. Consider renaming the parameter to provide clearer differentiation.

Apply this diff to rename the parameter:

   children: KeyStatFilterTag.values.map(
     (element) {
       return ChipButton(
         title: element.getString(context),
         isSelected: selectedTag == element,
         onTap: () {
           context.pop();
-          onTap(element);
+          onFilterTap(element);
         },
       );
     },
   ).toList(),

And update the parameter name accordingly:

-    required void Function(KeyStatFilterTag) onTap,
+    required void Function(KeyStatFilterTag) onFilterTap,
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 5ec27fc and fc6ec28.

📒 Files selected for processing (7)
  • data/lib/api/match/match_model.dart (1 hunks)
  • khelo/assets/locales/app_en.arb (1 hunks)
  • khelo/lib/ui/flow/matches/add_match/components/pitch_selection_view.dart (2 hunks)
  • khelo/lib/ui/flow/score_board/components/select_wicket_type_sheet.dart (2 hunks)
  • khelo/lib/ui/flow/tournament/detail/tabs/tournament_detail_stats_tab.dart (3 hunks)
  • khelo/lib/ui/flow/tournament/detail/tournament_detail_view_model.dart (3 hunks)
  • style/lib/button/chip_button.dart (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • khelo/assets/locales/app_en.arb
🔇 Additional comments (7)
style/lib/button/chip_button.dart (1)

12-18: LGTM! Constructor follows Flutter best practices.

The constructor is well-designed with:

  • Const constructor for better performance
  • Appropriate use of required annotation
  • Sensible default value for isSelected
khelo/lib/ui/flow/matches/add_match/components/pitch_selection_view.dart (2)

6-6: LGTM: Import added for new ChipButton component

The import is correctly placed and properly utilized in the code.


32-38: LGTM: Clean implementation using standardized ChipButton

The refactoring simplifies the code by using the new ChipButton component while maintaining the same functionality. The implementation is clean and follows good Flutter practices.

Let's verify the consistent usage of ChipButton across the codebase:

✅ Verification successful

ChipButton implementation is consistent across the codebase

The verification shows that:

  • ChipButton is used consistently in 3 different views with the same props pattern (title, isSelected, onTap)
  • The base ChipButton component in style/lib/button/chip_button.dart provides a standardized implementation
  • Only two legitimate Chip usages exist - one in ChipButton itself and another in SecondaryButton, both in the style library
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistent ChipButton usage patterns
# Expected: Similar padding and styling across different views

# Search for ChipButton usage patterns
rg -l "ChipButton" | xargs rg -A 3 "ChipButton\("

# Check for any remaining custom chip implementations that should be migrated
rg -l "Chip\(" | xargs rg -A 3 "Chip\("

Length of output: 2303

khelo/lib/ui/flow/score_board/components/select_wicket_type_sheet.dart (1)

10-10: LGTM! Good use of the shared button component.

The change from custom implementation to using the shared ChipButton component promotes better code reuse and UI consistency.

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

11-11: LGTM: Import for localization.

The added import for context extensions is necessary for localization support in the KeyStatFilterTag enum.


186-196: LGTM: Improved match filtering and team stats calculation.

The changes effectively simplify the code by:

  1. Using a clear filter for finished matches
  2. Leveraging the new teamStat extension method
data/lib/api/match/match_model.dart (1)

428-433: LGTM: Utility methods are well-implemented.

The _getTeam and _getOpponentTeam methods are concise and serve their purpose well.

@canopas canopas deleted a comment from coderabbitai bot Nov 7, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 7, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 7, 2024
@canopas canopas deleted a comment from coderabbitai bot Nov 7, 2024
@cp-mayank cp-mayank merged commit 29a3043 into main Nov 7, 2024
2 checks passed
@cp-mayank cp-mayank deleted the Mayank/refactor-tournament-detail-stats-filter branch November 7, 2024 12:49
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