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

Share option with deep linking #164

Merged
merged 31 commits into from
Jan 9, 2025
Merged

Conversation

cp-mayank
Copy link
Collaborator

@cp-mayank cp-mayank commented Jan 8, 2025

  • Share tournament , match and team via share options with deep linking
deep_linking.webm

Simulator Screen Recording - iPhone 16 Pro - 2025-01-09 at 17 21 29

Summary by CodeRabbit

Release Notes

  • New Features

    • Added deep linking support for tournaments, matches, and teams.
    • Introduced URL sharing functionality for tournaments, matches, and teams.
    • Updated app base URL to https://khelo.canopas.com.
    • Added support for the GTK plugin.
  • Improvements

    • Updated Gradle and Android plugin versions.
    • Enhanced platform-specific UI components.
    • Updated provisioning profile for iOS.
    • Improved action button visuals for better user experience.
  • Documentation

    • Created new documentation website with app details and features.
    • Added Apple App Site Association configuration for Universal Links.
    • Included configuration for .well-known directory in documentation.
    • Updated privacy policy and terms of service URLs.
  • Chores

    • Updated dependencies and plugin configurations across platforms.

Copy link

coderabbitai bot commented Jan 8, 2025

Walkthrough

This pull request introduces comprehensive deep linking support for the Khelo application across multiple platforms. The changes involve configuring app links for iOS, Android, macOS, and Windows, enabling users to navigate directly to specific tournament, match, and team pages via URLs. The implementation includes updating manifest files, adding platform-specific configurations, and integrating the app_links package to handle URI routing. Additionally, sharing functionality has been enhanced across various screens, allowing users to share tournament, match, and team links.

Changes

File Change Summary
khelo/android/app/src/main/AndroidManifest.xml Added deep linking configuration, new intent filters, and reordered attributes
khelo/android/gradle/wrapper/gradle-wrapper.properties Updated distributionUrl from Gradle 8.3 to 8.9
khelo/android/settings.gradle Updated com.android.application plugin version from 8.2.0 to 8.7.3
khelo/lib/main.dart Added appBaseUrl constant
khelo/lib/ui/flow/app_links/app_links_handler.dart Created new class for handling deep links
khelo/lib/ui/flow/main/main_screen.dart Integrated AppLinksHandler for deep link management
khelo/lib/ui/flow/matches/match_detail/match_detail_tab_screen.dart, khelo/lib/ui/flow/team/detail/team_detail_screen.dart, khelo/lib/ui/flow/tournament/detail/tournament_detail_screen.dart Added sharing functionality
khelo/lib/ui/flow/profile/profile_screen.dart Updated URLs for privacy policy and terms
khelo/ios/Runner/Info.plist Added FlutterDeepLinkingEnabled key
khelo/ios/Runner/Runner.entitlements Added associated domains for app links
khelo/linux/flutter/generated_plugin_registrant.cc, khelo/windows/flutter/generated_plugin_registrant.cc Registered new plugins for app links
docs/index.html, docs/.well-known/apple-app-site-association, docs/_config.yml Added new documentation and configuration for Universal Links

Possibly related PRs

Poem

🐰 Deep links hopping through the app,
Tournaments, matches - no more gap!
Sharing magic with a gentle tap,
Khelo's paths now open like a map,
Connecting players in one swift wrap! 🏏


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6b289c3 and 1b4041c.

📒 Files selected for processing (1)
  • docs/.well-known/apple-app-site-association (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/.well-known/apple-app-site-association

Finishing Touches

  • 📝 Generate Docstrings

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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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: 6

🧹 Nitpick comments (8)
khelo/lib/ui/flow/team/detail/team_detail_screen.dart (1)

87-103: Extract share button to a reusable widget.

The share button implementation is duplicated across multiple screens. Consider extracting it to a reusable widget to maintain consistency and reduce code duplication.

Create a new widget file lib/components/share_button.dart:

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:share_plus/share_plus.dart';
import 'package:style/button/action_button.dart';
import 'package:style/extensions/context_extensions.dart';

class ShareButton extends StatelessWidget {
  final String url;

  const ShareButton({super.key, required this.url});

  @override
  Widget build(BuildContext context) {
    return actionButton(
      context,
      icon: Icon(
        Platform.isIOS ? Icons.share : Icons.share_outlined,
        size: 20,
        color: context.colorScheme.textPrimary,
      ),
      onPressed: () async {
        try {
          await Share.shareUri(Uri.parse(url));
        } catch (e) {
          if (context.mounted) {
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(content: Text(context.l10n.common_share_error ?? 'Failed to share')),
            );
          }
        }
      },
    );
  }
}

Then update the current implementation:

 if (!widget.showAddButton) ...[
-  actionButton(
-    context,
-    icon: Icon(
-      Platform.isIOS ? Icons.share : Icons.share_outlined,
-      size: 20,
-      color: context.colorScheme.textPrimary,
-    ),
-    onPressed: () =>
-        Share.shareUri(Uri.parse("$appBaseUrl/team/${widget.teamId}")),
-  ),
+  ShareButton(url: "$appBaseUrl/team/${widget.teamId}"),
   if (state.team?.isAdminOrOwner(state.currentUserId) ?? false)
     moreOptionButton(
khelo/lib/ui/flow/tournament/detail/tournament_detail_screen.dart (2)

267-287: Simplify container styling and add error handling.

The container styling can be simplified, and error handling should be added to the share action.

 Widget _shareButton(BuildContext context, {required Function() onShareTap}) {
   return actionButton(
     context,
-    onPressed: onShareTap,
+    onPressed: () async {
+      try {
+        await onShareTap();
+      } catch (e) {
+        if (context.mounted) {
+          ScaffoldMessenger.of(context).showSnackBar(
+            SnackBar(content: Text(context.l10n.common_share_error ?? 'Failed to share')),
+          );
+        }
+      }
+    },
     icon: Container(
       height: 28,
       width: 28,
       decoration: BoxDecoration(
         shape: BoxShape.circle,
-        color:
-            context.colorScheme.containerHighOnSurface.withValues(alpha: 0.4),
+        color: context.colorScheme.containerHighOnSurface.withOpacity(0.4),
       ),
       alignment: Alignment.center,
       child: Icon(
         Platform.isIOS ? Icons.share : Icons.share_outlined,
         size: 20,
         color: context.colorScheme.textPrimary,
       ),
     ),
   );
 }

Line range hint 1-1: Consider implementing a dedicated deep linking service.

The current implementation duplicates URL construction logic across screens. Consider creating a dedicated service to manage deep links:

  1. Centralize deep link URL construction
  2. Add route validation
  3. Handle deep link analytics
  4. Manage deep link parameters

Example implementation:

// lib/services/deep_linking_service.dart
class DeepLinkingService {
  static const String baseUrl = String.fromEnvironment('APP_BASE_URL');
  
  static Uri generateMatchLink(String matchId) {
    return Uri.parse('$baseUrl/match/$matchId');
  }
  
  static Uri generateTeamLink(String teamId) {
    return Uri.parse('$baseUrl/team/$teamId');
  }
  
  static Uri generateTournamentLink(String tournamentId) {
    return Uri.parse('$baseUrl/tournament/$tournamentId');
  }
  
  static Future<void> share(Uri uri) async {
    try {
      await Share.shareUri(uri);
    } catch (e) {
      // Handle errors, log analytics
      rethrow;
    }
  }
}
khelo/lib/ui/flow/app_links/app_links_handler.dart (2)

8-10: Consider using an enum for route prefixes.

Convert string constants to an enum to improve type safety and maintainability.

-const String _routePrefixTournament = 'tournament';
-const String _routePrefixMatch = 'match';
-const String _routePrefixTeam = 'team';
+enum RoutePrefix {
+  tournament('tournament'),
+  match('match'),
+  team('team');
+
+  final String value;
+  const RoutePrefix(this.value);
+}
🧰 Tools
🪛 GitHub Actions: Dart Format & Analyze

[warning] File required formatting changes and was automatically formatted


12-52: Add documentation and improve error handling.

The class would benefit from:

  1. Class-level documentation explaining its purpose
  2. Method documentation
  3. More descriptive error messages

Add documentation:

+/// Handles deep linking functionality for the application.
+/// Processes URIs for tournaments, matches, and teams.
 class AppLinksHandler {
   final _appLinks = AppLinks();
   StreamSubscription<Uri>? _linkSubscription;

+  /// Initializes the deep link handler and starts listening for URI events.
+  /// 
+  /// The [context] is used for navigation and must remain mounted during URI processing.
   void init(BuildContext context) {
     // ... existing implementation ...
   }

+  /// Cleans up resources by canceling the URI link subscription.
   void dispose() {
     _linkSubscription?.cancel();
   }
 }
🧰 Tools
🪛 GitHub Actions: Dart Format & Analyze

[warning] File required formatting changes and was automatically formatted

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

76-76: Document padding adjustments and use named constants

The asymmetric padding values (64 left, 84 right) are not documented. Consider:

  1. Adding a comment explaining the padding adjustment
  2. Using named constants for these magic numbers
  3. Documenting why the padding is asymmetric
+                  // Additional right padding to accommodate the share button
+                  padding: const EdgeInsets.only(
+                    left: kTitleLeftPadding,  // 64
+                    right: kTitleRightPadding, // 84: accounts for back and share buttons
+                  ),
-                  padding: const EdgeInsets.only(left: 64, right: 84),
khelo/lib/ui/flow/main/main_screen.dart (2)

37-47: Consider initializing handlers in a more structured way.

While the initialization logic is correct, consider refactoring the handler initializations into a separate method for better maintainability.

Here's a suggested refactor:

  late final NotificationHandler notificationHandler;
  late final AppLinksHandler _appLinksHandler;

+ void _initializeHandlers(BuildContext context) {
+   notificationHandler = ref.read(notificationHandlerProvider);
+   _appLinksHandler = AppLinksHandler();
+   
+   notificationHandler.init(context);
+   _appLinksHandler.init(context);
+ }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
-   _appLinksHandler = AppLinksHandler();
-   notificationHandler = ref.read(notificationHandlerProvider);
    runPostFrame(() {
-     notificationHandler.init(context);
-     _appLinksHandler.init(context);
+     _initializeHandlers(context);
    });
  }
🧰 Tools
🪛 GitHub Actions: Dart Format & Analyze

[warning] File required formatting changes and was automatically formatted


61-65: Fix formatting issues.

The pipeline reported formatting issues. Please run dart format on the file.

🧰 Tools
🪛 GitHub Actions: Dart Format & Analyze

[warning] File required formatting changes and was automatically formatted

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b3ad596 and e0defa3.

⛔ Files ignored due to path filters (1)
  • khelo/pubspec.lock is excluded by !**/*.lock
📒 Files selected for processing (16)
  • khelo/android/app/src/main/AndroidManifest.xml (1 hunks)
  • khelo/android/gradle/wrapper/gradle-wrapper.properties (1 hunks)
  • khelo/android/settings.gradle (1 hunks)
  • khelo/lib/main.dart (1 hunks)
  • khelo/lib/ui/flow/app_links/app_links_handler.dart (1 hunks)
  • khelo/lib/ui/flow/main/main_screen.dart (3 hunks)
  • khelo/lib/ui/flow/matches/match_detail/match_detail_tab_screen.dart (2 hunks)
  • khelo/lib/ui/flow/team/detail/team_detail_screen.dart (4 hunks)
  • khelo/lib/ui/flow/tournament/detail/components/flexible_space.dart (1 hunks)
  • khelo/lib/ui/flow/tournament/detail/tournament_detail_screen.dart (4 hunks)
  • khelo/linux/flutter/generated_plugin_registrant.cc (1 hunks)
  • khelo/linux/flutter/generated_plugins.cmake (1 hunks)
  • khelo/macos/Flutter/GeneratedPluginRegistrant.swift (2 hunks)
  • khelo/pubspec.yaml (1 hunks)
  • khelo/windows/flutter/generated_plugin_registrant.cc (2 hunks)
  • khelo/windows/flutter/generated_plugins.cmake (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • khelo/lib/main.dart
🧰 Additional context used
🪛 GitHub Actions: Dart Format & Analyze
khelo/lib/ui/flow/app_links/app_links_handler.dart

[warning] File required formatting changes and was automatically formatted

khelo/lib/ui/flow/main/main_screen.dart

[warning] File required formatting changes and was automatically formatted

🔇 Additional comments (12)
khelo/android/gradle/wrapper/gradle-wrapper.properties (1)

5-5: Verify Gradle version compatibility and necessity

The upgrade from Gradle 8.3 to 8.9 is a significant version jump. While keeping dependencies up-to-date is good practice, please ensure:

  1. This version is compatible with the Android Gradle Plugin 8.7.3
  2. This update is necessary for the deep linking implementation
✅ Verification successful

Gradle 8.9 upgrade is appropriate

The upgrade is compatible with your Android configuration and aligns with the deep linking implementation. The project's modern Flutter SDK and dependencies justify using the latest stable Gradle version.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the project has any explicit Gradle version requirements
fd -t f "build.gradle" -x cat {} \; | grep -i "gradle"

# Check for any deep linking related configurations that might require this update
fd -t f -e gradle -e properties | xargs grep -l "android\.intent\.action\.VIEW\|android\.intent\.category\.BROWSABLE"

Length of output: 461


Script:

#!/bin/bash
# Check Android Gradle Plugin version
fd -t f "build.gradle" -x cat {} \; | grep -i "com.android.tools.build:gradle"

# Check Flutter version and related files
fd -t f "pubspec.yaml|pubspec.lock" -x cat {} \;

# Check AndroidManifest.xml for deep linking
fd -t f "AndroidManifest.xml" -x cat {} \; | grep -A 5 "intent-filter"

Length of output: 64046

khelo/android/settings.gradle (1)

26-26: Review plugin version compatibility matrix

The Android Gradle Plugin has been updated to 8.7.3, but other plugins remain unchanged:

  • google-services: 4.3.15
  • crashlytics: 2.8.1
  • kotlin.android: 1.8.22

Please verify:

  1. Compatibility between these plugin versions
  2. If other plugins need updates
  3. If this specific version is required for deep linking implementation
khelo/linux/flutter/generated_plugins.cmake (1)

7-7: LGTM! Auto-generated file changes.

The addition of the GTK plugin is consistent with the deep linking implementation requirements.

Note that this is an auto-generated file. Ensure you've properly configured the Flutter project to include the GTK plugin rather than manually editing this file.

khelo/linux/flutter/generated_plugin_registrant.cc (1)

17-19: LGTM! Proper plugin registration.

The GTK plugin registration follows the correct pattern and is properly integrated with the existing plugin registration flow.

khelo/windows/flutter/generated_plugins.cmake (1)

6-6: LGTM! Auto-generated file changes.

The addition of the app_links plugin is essential for implementing the deep linking functionality.

Note that this is an auto-generated file. Ensure you've properly added the app_links dependency to your pubspec.yaml rather than manually editing this file.

khelo/lib/ui/flow/app_links/app_links_handler.dart (1)

32-32: Fix formatting issues.

Add space after if keyword to maintain consistent formatting.

-if(pathSegments.first == _routePrefixMatch){
+if (pathSegments.first == _routePrefixMatch) {

-if(pathSegments.first == _routePrefixTeam){
+if (pathSegments.first == _routePrefixTeam) {

Also applies to: 38-38

🧰 Tools
🪛 GitHub Actions: Dart Format & Analyze

[warning] File required formatting changes and was automatically formatted

khelo/android/app/src/main/AndroidManifest.xml (1)

12-14: Review security implications of exported activity

The MainActivity is marked as exported and handles deep links. Ensure proper validation of incoming deep links to prevent potential security issues.

✅ Verification successful

Deep link handling is properly secured

The exported activity is properly secured through multiple measures:

  • HTTPS-only scheme configuration
  • Android App Links verification (autoVerify="true")
  • Single trusted domain (khelo.canopas.com)
  • Deep linking disabled via manifest flag
  • No custom URL schemes that could be exploited
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for deep link validation in the codebase
echo "Searching for deep link validation..."
rg -l "app_links.*validate|uri.*validate" lib/

Length of output: 178


Script:

#!/bin/bash
# Check for deep link configurations and handling
echo "Checking AndroidManifest.xml for deep link intent filters..."
cat khelo/android/app/src/main/AndroidManifest.xml

echo -e "\nSearching for deep link handling patterns..."
rg -i "deep.*link|uri|url|scheme|intent" --type dart --type java --type kotlin -A 3

echo -e "\nSearching for URL validation patterns..."
rg -i "validate.*url|sanitize.*url|check.*url" --type dart --type java --type kotlin

Length of output: 76811


Script:

#!/bin/bash
# Check for custom URL schemes and additional deep link handlers
echo "Checking for custom URL schemes in manifest..."
rg -i "android:scheme|<data.*scheme" khelo/android/app/src/main/AndroidManifest.xml

echo -e "\nSearching for deep link/URL handling patterns..."
rg -i "handlelink|onlink|deeplink|parseurl|parseuri" --type dart -A 3

Length of output: 421

khelo/windows/flutter/generated_plugin_registrant.cc (1)

21-22: LGTM!

The AppLinks plugin registration is correctly added.

khelo/macos/Flutter/GeneratedPluginRegistrant.swift (1)

28-28: LGTM!

The AppLinks plugin registration is correctly added.

khelo/pubspec.yaml (1)

59-59: LGTM! Verify the app_links version.

The addition of the app_links package is appropriate for implementing deep linking functionality. The version is pinned which is good for stability.

Run this script to check for any recent critical updates or security advisories:

✅ Verification successful

Current version 6.3.2 is appropriate, with 6.3.3 available

The pinned version 6.3.2 is stable and recent. While version 6.3.3 is available, the difference is minor. No security vulnerabilities were found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check latest version and security advisories for app_links package
curl -s https://pub.dev/packages/app_links.json | jq -r '.versions[-1].version'
gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: PUB, package: "app_links") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
      firstPatchedVersion {
        identifier
      }
    }
  }
}'

Length of output: 492


Script:

#!/bin/bash
# Retry checking latest version with modified jq query
curl -s https://pub.dev/api/packages/app_links | jq -r '.latest.version'

Length of output: 78

khelo/lib/ui/flow/main/main_screen.dart (2)

10-10: LGTM! Import statement is correctly placed.

The import for AppLinksHandler is appropriately grouped with other flow-related imports.

🧰 Tools
🪛 GitHub Actions: Dart Format & Analyze

[warning] File required formatting changes and was automatically formatted


43-47: Add error handling for deep link initialization.

Consider adding error handling for deep link initialization failures to ensure graceful degradation of the sharing feature.

Run this script to check if error handling exists in the AppLinksHandler implementation:

🧰 Tools
🪛 GitHub Actions: Dart Format & Analyze

[warning] File required formatting changes and was automatically formatted

@canopas canopas deleted a comment from coderabbitai bot Jan 8, 2025
@canopas canopas deleted a comment from coderabbitai bot Jan 8, 2025
@canopas canopas deleted a comment from coderabbitai bot Jan 8, 2025
@canopas canopas deleted a comment from coderabbitai bot Jan 8, 2025
@canopas canopas deleted a comment from coderabbitai bot Jan 8, 2025
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: 2

🧹 Nitpick comments (4)
style/lib/button/more_option_button.dart (1)

15-17: Consider making the CircleAvatar radius responsive to the size parameter

Currently, the CircleAvatar has a fixed radius of 16 while the size parameter only affects the icon. This could lead to layout inconsistencies when different sizes are needed.

Consider this implementation:

-      icon: CircleAvatar(
-        radius: 16,
+      icon: CircleAvatar(
+        radius: size * 0.75, // Scale radius relative to icon size
khelo/lib/ui/flow/tournament/detail/tournament_detail_screen.dart (1)

262-277: Extract common circle avatar styling

The styling for both share and back buttons is identical. Consider extracting the common CircleAvatar styling to reduce duplication.

+ Widget _buildCircleButton(BuildContext context, {
+   required VoidCallback onPressed,
+   required IconData icon,
+   double iconSize = 20,
+   double radius = 16,
+ }) {
+   return actionButton(
+     context,
+     onPressed: onPressed,
+     icon: CircleAvatar(
+       radius: radius,
+       backgroundColor: context.colorScheme.containerHighOnSurface.withValues(alpha: 0.4),
+       child: Icon(
+         icon,
+         size: iconSize,
+         color: context.colorScheme.textPrimary,
+       ),
+     ),
+   );
+ }

  Widget _backButton(BuildContext context) {
-   return actionButton(context,
-       onPressed: context.pop,
-       icon: CircleAvatar(
-         radius: 16,
-         backgroundColor: context.colorScheme.containerHighOnSurface.withValues(alpha: 0.4),
-         child: Icon(
-           Platform.isIOS ? Icons.arrow_back_ios_new : Icons.arrow_back,
-           size: 20,
-           color: context.colorScheme.textPrimary,
-         ),
-       ));
+   return _buildCircleButton(
+     context,
+     onPressed: context.pop,
+     icon: Platform.isIOS ? Icons.arrow_back_ios_new : Icons.arrow_back,
+   );
  }

  Widget _shareButton(BuildContext context, {required Function() onShareTap}) {
-   return actionButton(
-     context,
-     onPressed: onShareTap,
-     icon: CircleAvatar(
-       radius: 16,
-       backgroundColor: context.colorScheme.containerHighOnSurface.withValues(alpha: 0.4),
-       child: Icon(
-         Platform.isIOS ? Icons.share : Icons.share_outlined,
-         size: 20,
-         color: context.colorScheme.textPrimary,
-       ),
-     ),
-   );
+   return _buildCircleButton(
+     context,
+     onPressed: onShareTap,
+     icon: Platform.isIOS ? Icons.share : Icons.share_outlined,
+   );
  }
khelo/lib/ui/flow/app_links/app_links_handler.dart (2)

8-10: Consider moving route constants to a dedicated constants file.

These route prefix constants might be needed in other parts of the app (e.g., URL generation for sharing). Moving them to a dedicated constants file would improve reusability and maintainability.


16-47: Add documentation for the init method.

Consider adding documentation explaining the method's purpose, parameters, and expected behavior.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e0defa3 and 4c8b4a3.

📒 Files selected for processing (5)
  • khelo/android/app/src/main/AndroidManifest.xml (1 hunks)
  • khelo/lib/ui/flow/app_links/app_links_handler.dart (1 hunks)
  • khelo/lib/ui/flow/main/main_screen.dart (3 hunks)
  • khelo/lib/ui/flow/tournament/detail/tournament_detail_screen.dart (5 hunks)
  • style/lib/button/more_option_button.dart (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • khelo/android/app/src/main/AndroidManifest.xml
  • khelo/lib/ui/flow/main/main_screen.dart
🔇 Additional comments (7)
style/lib/button/more_option_button.dart (1)

15-17: Good choice using CircleAvatar for circular button styling!

The switch from Container to CircleAvatar is a better semantic choice for circular buttons, as it handles the circular clipping automatically.

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

18-18: LGTM! Import aligns with sharing functionality requirement.

The addition of the share_plus package import is appropriate for implementing the sharing feature.


250-253: LGTM! Addressed previous review feedback.

The back button now uses CircleAvatar as suggested in the previous review, maintaining consistency with the share button implementation.


115-132: Verify appBaseUrl configuration across environments

The share URL construction looks correct, but we should ensure appBaseUrl is properly configured across different environments.

Run this script to verify the base URL configuration:

Additionally, consider extracting the URL construction to a dedicated method or constant for better maintainability:

+ // Add this at the top of the file with other constants
+ String _getTournamentShareUrl(String tournamentId) => "$appBaseUrl/tournament/$tournamentId";

- onShareTap: () => Share.shareUri(Uri.parse(
-     "$appBaseUrl/tournament/${state.tournament!.id}")),
+ onShareTap: () => Share.shareUri(Uri.parse(
+     _getTournamentShareUrl(state.tournament!.id))),
✅ Verification successful

appBaseUrl is properly configured

The base URL is correctly defined as a constant in main.dart and consistently used across detail screens. The suggested URL extraction is optional given the simple, one-time usage in this file.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for appBaseUrl configuration across environment files
rg -l "appBaseUrl" --type dart

Length of output: 238


Script:

#!/bin/bash
# Check appBaseUrl definition and usage
echo "=== main.dart definition ==="
rg "appBaseUrl" khelo/lib/main.dart -B 2 -A 2

echo -e "\n=== Usage in detail screens ==="
rg "appBaseUrl.*tournament|team|match" --type dart -B 1 -A 1

Length of output: 73958

khelo/lib/ui/flow/app_links/app_links_handler.dart (3)

12-14: LGTM! Fields are properly encapsulated.

Good practice using nullable StreamSubscription for proper cleanup.


49-51: LGTM! Proper cleanup in dispose method.

Good practice canceling the subscription to prevent memory leaks.


1-52: Verify deep linking implementation completeness.

Please ensure:

  1. Deep link URL format validation is in place
  2. Error handling covers malformed URLs
  3. Unit tests are added for various scenarios:
    • Valid URLs for each route type
    • Invalid/malformed URLs
    • Empty paths
    • Missing IDs

Run the following script to check for test coverage:

✅ Verification successful

Deep linking implementation is properly structured and secure.

The current implementation:

  • Handles URI parsing safely through the AppLinks package
  • Validates path segments and handles empty paths
  • Includes proper error handling with try-catch blocks
  • Maintains context safety with mounted checks
  • Follows a simple, secure /{type}/{id} URL pattern
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for test file existence and coverage
fd -e dart "app_links.*test\.dart$"

# Check for URL validation and error handling patterns
rg -A 5 "Uri|try|catch" "lib/ui/flow/app_links/"

Length of output: 149


Script:

#!/bin/bash
# Find the correct path first
fd -t f "app_links_handler.dart$"

# Look for test files
fd -e dart "test" -e dart "spec"

# Search for URL validation and error handling
rg -A 5 "Uri|try|catch" --type dart

# Look for URL validation utilities
ast-grep --pattern 'class $_ { 
  $$$
  validate($_, $_) {
    $$$
  }
  $$$
}'

Length of output: 96734

@canopas canopas deleted a comment from coderabbitai bot Jan 9, 2025
@canopas canopas deleted a comment from coderabbitai bot Jan 9, 2025
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: 2

🧹 Nitpick comments (1)
khelo/lib/ui/flow/team/detail/team_detail_screen.dart (1)

87-103: Consider extracting share button to a reusable component.

The share button implementation is duplicated across screens. Consider extracting it into a reusable component to maintain DRY principles and ensure consistent behavior.

Example implementation:

// lib/components/share_button.dart
class ShareButton extends StatelessWidget {
  final String path;
  
  const ShareButton({required this.path});
  
  @override
  Widget build(BuildContext context) {
    return actionButton(
      context,
      icon: Icon(
        Platform.isIOS ? Icons.share : Icons.share_outlined,
        size: 20,
        color: context.colorScheme.textPrimary,
      ),
      onPressed: () => Share.shareUri(
        Uri.parse("${Platform.isIOS ? appIOSBaseUrl : appBaseUrl}/$path"),
      ),
    );
  }
}

Usage:

-actionButton(
-  context,
-  icon: Icon(
-    Platform.isIOS ? Icons.share : Icons.share_outlined,
-    size: 20,
-    color: context.colorScheme.textPrimary,
-  ),
-  onPressed: () => Share.shareUri(Uri.parse(
-      "${Platform.isIOS ? appIOSBaseUrl : appBaseUrl}/team/${widget.teamId}")),
-),
+ShareButton(path: "team/${widget.teamId}"),
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4c8b4a3 and 975ab01.

⛔ Files ignored due to path filters (1)
  • khelo/ios/Podfile.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • khelo/ios/Runner/Info.plist (1 hunks)
  • khelo/lib/main.dart (1 hunks)
  • khelo/lib/ui/flow/matches/match_detail/match_detail_tab_screen.dart (2 hunks)
  • khelo/lib/ui/flow/team/detail/team_detail_screen.dart (4 hunks)
  • khelo/lib/ui/flow/tournament/detail/tournament_detail_screen.dart (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • khelo/lib/main.dart
  • khelo/lib/ui/flow/tournament/detail/tournament_detail_screen.dart
🔇 Additional comments (4)
khelo/lib/ui/flow/matches/match_detail/match_detail_tab_screen.dart (2)

1-1: LGTM! Required imports added for sharing functionality.

The new imports are appropriate for implementing the share feature:

  • dart:io for platform-specific checks
  • share_plus for sharing capabilities
  • UI components for consistent button styling

Also applies to: 11-12, 14-14


59-70: Verify the base URL configuration for deep linking.

The implementation looks good but relies on global variables appIOSBaseUrl and appBaseUrl. Please ensure these are properly configured in the production environment.

Let's verify the base URL configuration:

✅ Verification successful

Base URL configuration for deep linking is properly configured

The base URLs are correctly defined as constants in main.dart and are consistently used across the codebase with proper deep linking patterns for both web and iOS platforms.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for base URL configurations
rg -l "appIOSBaseUrl|appBaseUrl" --type dart

# Check their usage across the codebase
rg "appIOSBaseUrl|appBaseUrl" --type dart -A 2

Length of output: 1562

khelo/lib/ui/flow/team/detail/team_detail_screen.dart (2)

1-1: LGTM! Required imports added consistently.

The imports align with those in the match detail screen, maintaining consistency across the codebase.

Also applies to: 19-19, 28-28


87-103: Verify the conditional rendering logic.

The share and more options buttons are shown only when showAddButton is false. This seems counterintuitive - verify if this is the intended behavior.

Let's check the usage of showAddButton:

✅ Verification successful

The conditional rendering logic is correct and intentional.

The screen serves two purposes:

  1. Team selection mode (showAddButton: true) - Shows only an Add button
  2. Team viewing mode (showAddButton: false) - Shows sharing and admin options
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Find where TeamDetailScreen is instantiated
ast-grep --pattern 'TeamDetailScreen(
  $$$
  showAddButton: $_,
  $$$
)'

Length of output: 75


Script:

#!/bin/bash
# Find files containing TeamDetailScreen
rg -l "TeamDetailScreen"

# Find the widget definition and surrounding context
rg "class TeamDetailScreen" -A 10

# Search for showAddButton usage with surrounding context
rg "showAddButton" -A 5 -B 5

Length of output: 11582

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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between beda469 and e890f5c.

📒 Files selected for processing (1)
  • khelo/ios/Runner.xcodeproj/project.pbxproj (1 hunks)

@@ -757,7 +757,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.canopas.khelo;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "provision-khelo-distribution-2024-06-12";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "provision-khelo-distribution-2025-01-09";
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

⚠️ Deep linking configuration is incomplete

The provisioning profile update alone is insufficient. Critical configuration issues found:

  • Deep linking is explicitly disabled (FlutterDeepLinkingEnabled: false)
  • Missing associated domains configuration for universal links
  • URL schemes are configured but won't work until deep linking is enabled
🔗 Analysis chain

LGTM! Provisioning profile updated for deep linking support.

The provisioning profile has been updated with a new expiration date (2025-01-09), which is necessary for supporting the deep linking functionality.

Please ensure that:

  1. The new provisioning profile includes the required associated domains for deep linking
  2. The URL scheme 'kheloapp' is properly configured in the app's Info.plist
  3. The team has access to the new provisioning profile in the Apple Developer portal

Run this script to verify the URL scheme configuration:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify URL scheme configuration in Info.plist
# Test: Check if the URL scheme is properly configured
cat khelo/ios/Runner/Info.plist | grep -A 5 CFBundleURLTypes

Length of output: 347


Script:

#!/bin/bash
# Get complete URL scheme configuration and associated domains
echo "=== Complete URL Types Configuration ==="
cat khelo/ios/Runner/Info.plist | grep -A 15 CFBundleURLTypes

echo -e "\n=== Associated Domains Configuration ==="
cat khelo/ios/Runner/Info.plist | grep -A 5 "com.apple.developer.associated-domains"

Length of output: 1039

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

🧹 Nitpick comments (3)
docs/.well-known/apple-app-site-association (1)

9-14: Review the root path configuration

The root path component "/" is very permissive and will match all URLs on your domain. Consider:

  1. Removing it if not needed
  2. Or adding specific paths that your app should handle
  3. Ensuring your web server properly handles URLs that shouldn't be opened in the app
 "components":[
-  { "/":"/" },
   { "/":"/team/*" }, 
   { "/":"/tournament/*" },
   { "/":"/match/*" }
 ]
khelo/ios/Runner/Runner.entitlements (1)

7-10: Configuration looks good, minor formatting suggestion

The associated domains configuration is correct and properly matches the domain in the apple-app-site-association file.

Consider fixing the indentation for consistency:

 <key>com.apple.developer.associated-domains</key>
-    <array>
-    	<string>applinks:khelo.canopas.com</string>
-    </array>
+	<array>
+		<string>applinks:khelo.canopas.com</string>
+	</array>
khelo/lib/ui/flow/tournament/detail/tournament_detail_screen.dart (1)

Line range hint 250-274: Consider extracting common CircleAvatar styling

Both _backButton and _shareButton use similar CircleAvatar styling. Consider extracting this into a reusable widget to improve maintainability.

Example implementation:

Widget _circleIconButton(
  BuildContext context, {
  required VoidCallback onPressed,
  required IconData icon,
  double radius = 16,
  double iconSize = 20,
}) {
  return actionButton(
    context,
    onPressed: onPressed,
    icon: CircleAvatar(
      radius: radius,
      backgroundColor: context.colorScheme.containerHighOnSurface.withValues(alpha: 0.4),
      child: Icon(
        icon,
        size: iconSize,
        color: context.colorScheme.textPrimary,
      ),
    ),
  );
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e890f5c and 948deab.

📒 Files selected for processing (9)
  • docs/.well-known/apple-app-site-association (1 hunks)
  • docs/_layouts/default.html (1 hunks)
  • khelo/ios/Runner/Info.plist (1 hunks)
  • khelo/ios/Runner/Runner.entitlements (1 hunks)
  • khelo/lib/main.dart (1 hunks)
  • khelo/lib/ui/flow/matches/match_detail/match_detail_tab_screen.dart (2 hunks)
  • khelo/lib/ui/flow/profile/profile_screen.dart (1 hunks)
  • khelo/lib/ui/flow/team/detail/team_detail_screen.dart (4 hunks)
  • khelo/lib/ui/flow/tournament/detail/tournament_detail_screen.dart (5 hunks)
✅ Files skipped from review due to trivial changes (1)
  • khelo/lib/ui/flow/profile/profile_screen.dart
🚧 Files skipped from review as they are similar to previous changes (4)
  • khelo/lib/main.dart
  • khelo/ios/Runner/Info.plist
  • khelo/lib/ui/flow/team/detail/team_detail_screen.dart
  • khelo/lib/ui/flow/matches/match_detail/match_detail_tab_screen.dart
🔇 Additional comments (6)
docs/_layouts/default.html (1)

2-2: LGTM!

The language attribute syntax using Liquid templating looks correct and follows Jekyll's conventions.

docs/.well-known/apple-app-site-association (1)

6-8: Verify the Apple Team ID

Please verify that S985H2T7J8 matches your Apple Developer account Team ID. An incorrect Team ID will prevent Universal Links from working.

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

18-18: LGTM! Import aligns with sharing functionality requirement.

The addition of the share_plus package import is appropriate for implementing the sharing feature.


262-277: Well-implemented share button with platform-specific considerations!

The implementation:

  • Uses platform-specific icons (iOS/Android)
  • Maintains UI consistency with other buttons
  • Properly utilizes theme context

250-253: Good job addressing the previous feedback!

The switch to CircleAvatar for the back button improves UI consistency.


115-132: Verify appBaseUrl configuration across environments

The share URL construction looks correct, but we should ensure the appBaseUrl is properly configured across different environments.

Let's verify the appBaseUrl configuration:

✅ Verification successful

appBaseUrl configuration is correct but could be improved

The appBaseUrl is correctly configured for production sharing links at 'https://khelo.canopas.com' and is used consistently across all sharing features. While the current implementation is safe for production use, consider introducing environment-specific configurations in future updates for better development and staging support.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for appBaseUrl definitions across the codebase
rg -l "appBaseUrl" --type dart

# Check for environment-specific configurations
rg "appBaseUrl.*=" --type dart -A 3

Length of output: 470


Script:

#!/bin/bash
# Check for environment configuration files
fd -e yaml -e json -e dart --full-path ".*env.*|.*config.*|.*flavor.*"

# Check for build configuration in pubspec.yaml
cat pubspec.yaml

# Check for any dart_defines or --dart-define usage in build scripts
fd -e sh -e yaml -e json --full-path ".*build.*"

Length of output: 187


Script:

#!/bin/bash
# Search for Flutter configuration files in different locations
fd -t f "pubspec.yaml|.*\.config\.dart"

# Look for any URL-related configurations or constants
rg -g "*.dart" "(?i)(url|base.*url|api.*url).*=.*['\"]http" -A 2

# Check for any flavor or environment-related code
rg -g "*.dart" "(?i)(flavor|environment|config|prod|dev|stage)" --type dart

Length of output: 19918

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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0ccd24d and 6aafc8e.

📒 Files selected for processing (3)
  • docs/.htaccess (1 hunks)
  • docs/index.html (1 hunks)
  • docs/well-known/apple-app-site-association (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • docs/.htaccess
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/index.html
🔇 Additional comments (2)
docs/well-known/apple-app-site-association (2)

11-13: LGTM! Deep linking paths are well-structured.

The wildcard paths for team, tournament, and match are correctly configured and align with the PR objectives for sharing functionality.


1-18: Verify Universal Links configuration requirements.

Please ensure the following requirements are met for Universal Links to work properly:

  1. The Team ID "S985H2T7J8" matches your Apple Developer account.
  2. This file must be served over HTTPS at https://khelo.canopas.com/.well-known/apple-app-site-association.
  3. The domain ownership must be verified in your Apple Developer account.

Run the following script to verify the file location and HTTPS serving:

@canopas canopas deleted a comment from coderabbitai bot Jan 9, 2025
…nking' into Mayank/share-option-with-deep-linking
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

🧹 Nitpick comments (1)
docs/.well-known/apple-app-site-association (1)

9-14: Consider adding path pattern restrictions

The current URL patterns (/*) are very permissive. Consider:

  1. Adding specific parameter constraints
  2. Limiting the depth of wildcards
  3. Adding validation for expected path parameters

Example: Replace /team/* with /team/\*?id=* to only match valid team URLs.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6aafc8e and 4a6def3.

⛔ Files ignored due to path filters (1)
  • docs/app_showcase.png is excluded by !**/*.png
📒 Files selected for processing (2)
  • docs/.well-known/apple-app-site-association (1 hunks)
  • docs/_config.yml (1 hunks)
🔇 Additional comments (2)
docs/.well-known/apple-app-site-association (1)

6-8: Verify the App ID configuration

Please ensure that:

  1. The Team ID S985H2T7J8 matches your Apple Developer account
  2. The bundle ID com.canopas.khelo matches your Xcode project configuration
✅ Verification successful

App ID configuration is correct

The App ID S985H2T7J8.com.canopas.khelo in the apple-app-site-association file is correctly configured, matching the Team ID and bundle identifier found in the iOS project configuration files.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the bundle ID in Info.plist matches
find . -name "Info.plist" -exec grep -l "com.canopas.khelo" {} \;

Length of output: 66


Script:

#!/bin/bash
# Find all plist files
echo "=== Finding all plist files ==="
fd -e plist

# Search for bundle ID in all files
echo -e "\n=== Searching for bundle ID ==="
rg -l "com.canopas.khelo"

# Search for files containing 'bundleId' or similar
echo -e "\n=== Searching for bundle identifier references ==="
rg -l -i "bundle.?id|CFBundleIdentifier"

Length of output: 1374


Script:

#!/bin/bash
# Check iOS configuration files
echo "=== iOS ExportOptions.plist ==="
cat "khelo/ios/Runner/ExportOptions.plist"

echo -e "\n=== iOS Info.plist Bundle ID ==="
rg "CFBundleIdentifier" "khelo/ios/Runner/Info.plist" -A 1

Length of output: 849

docs/_config.yml (1)

1-1: LGTM! Verify HTTPS accessibility

The configuration correctly includes the .well-known directory. For Universal Links to work:

  1. Ensure the apple-app-site-association file is served over HTTPS
  2. Verify it's served without a file extension

@cp-mayank cp-mayank merged commit ac9687b into main Jan 9, 2025
5 checks passed
@cp-mayank cp-mayank deleted the Mayank/share-option-with-deep-linking branch January 9, 2025 11:53
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