Skip to content

Conversation

@konti-aditi
Copy link
Contributor

Date: 27-03-2025

Developer Name: Aditi Shinde


Issue Ticket Number

#480

Description

This PR contains the code of both CLI and Expo app in the same repo.
CLI is the old app and expo is the recently created app which is the replica of the CLI app but in React-Native Expo.

Documentation Updated?

  • Yes
  • No

Under Feature Flag

  • Yes
  • No

Database Changes

  • Yes
  • No

Breaking Changes

  • Yes
  • No

Development Tested?

  • Yes
  • No

Screenshots

Screenshot 1

Test Coverage

Screenshot 1

Additional Notes

@coderabbitai
Copy link

coderabbitai bot commented Mar 27, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Summary by CodeRabbit

  • New Features
    • Introduced a streamlined GitHub authentication flow with deep linking support.
    • Added tab-based navigation featuring dedicated Home, Notify, and Profile screens for an improved user experience.
  • Style
    • Refreshed visual design with updated splash screens, adaptive icons, and cohesive color themes for a modern look.

These enhancements deliver a smoother sign-in process and a more intuitive, visually appealing interface.

Walkthrough

This update introduces a comprehensive set of new configuration files and source code additions. It adds gitignore files, Android build configurations (Gradle, wrapper, properties, settings), Android manifests, and Kotlin classes for the main activity and application. Several Android resource files (drawable, mipmap, colors, strings, and styles) are provided to support theming and UI. New Expo and TypeScript configuration files are included alongside multiple React Native components for authentication, tab navigation, and profile management. Additionally, constants for API endpoints and color schemes have been defined, and the previous Metro configuration file has been removed.

Changes

File(s) Change Summary
RDSExpoApp/.gitignore
RDSExpoApp/android/.gitignore
Added gitignore files to exclude node modules, build artifacts, native files, IDE/system files, and other non-essential files.
RDSExpoApp/android/build.gradle
RDSExpoApp/android/gradle.properties
RDSExpoApp/android/gradle/wrapper/gradle-wrapper.properties
RDSExpoApp/android/gradlew
RDSExpoApp/android/gradlew.bat
RDSExpoApp/android/settings.gradle
Introduced Android build configuration files and Gradle wrapper scripts that set up build tools, repositories, and project-wide properties.
RDSExpoApp/android/app/build.gradle
RDSExpoApp/android/app/proguard-rules.pro
RDSExpoApp/android/app/src/debug/AndroidManifest.xml
RDSExpoApp/android/app/src/main/AndroidManifest.xml
RDSExpoApp/android/app/src/main/java/.../MainActivity.kt
RDSExpoApp/android/app/src/main/java/.../MainApplication.kt
Added Android manifest files and Kotlin classes for MainActivity and MainApplication, plus ProGuard rules for code obfuscation and resource safeguarding.
RDSExpoApp/android/app/src/main/res/drawable/*
RDSExpoApp/android/app/src/main/res/mipmap-anydpi-v26/*
RDSExpoApp/android/app/src/main/res/values(-night)/colors.xml
RDSExpoApp/android/app/src/main/res/values/strings.xml
RDSExpoApp/android/app/src/main/res/values/styles.xml
Added resource files including drawables for icons and backgrounds, adaptive icons, color definitions, strings, and styles for theming and UI configuration.
RDSExpoApp/app.json
RDSExpoApp/package.json
RDSExpoApp/tsconfig.json
Introduced configuration files for Expo app settings, Node package management, and TypeScript compiler options.
RDSExpoApp/app/(tabs)/* (e.g. HomeScreen.tsx, NotifyScreen.tsx, ProfileScreen.tsx, _layout.tsx, index.tsx)
RDSExpoApp/app/_layout.tsx
RDSExpoApp/assets/svgs/github_logo.js
Added new React Native components and layouts for Home, Notify, Profile, and Auth screens. The updates include GitHub authentication via deep links, tab navigation, splash screen management, and an SVG component for the GitHub logo.
RDSExpoApp/constants/Colors.ts
RDSExpoApp/constants/apiConstant/{AuthApi.ts,BaseUrl.ts}
Defined constants for color themes and API endpoints including production and staging base URLs for authentication services.
RDSExpoApp/metro.config.js Removed the Metro bundler configuration file.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant AS as AuthScreen
    participant AT as AsyncStorage
    participant R as Router

    U->>AS: Launch App / Open AuthScreen
    AS->>AT: Check for token (github_token)
    AT-->>AS: Return token (or null)
    alt Token exists
        AS->>R: Redirect to HomeScreen
    else No token
        U->>AS: Tap "GitHub Sign In"
        AS->>AS: Build GitHub auth URL
        AS->>U: Open Browser with auth URL
        U->>AS: Return via deep link with token
        AS->>AT: Store github_token
        AS->>R: Redirect to HomeScreen
    end
Loading

Poem

Hopping through changes with a joyful beat,
New files and features make my code complete.
Gradle, manifests, and React screens align,
As I nibble on commits like fresh green vine.
With each merge, I hop toward a brighter design! 🐰💻


🪧 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.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @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: 34

🔭 Outside diff range comments (4)
RDSExpoApp/app/(tabs)/HomeScreen.tsx (1)

22-23: 🧹 Nitpick (assertive)

Remove trailing space

There's an unnecessary trailing space at the end of the file.

 });
-23
+
RDSExpoApp/app/(tabs)/NotifyScreen.tsx (1)

22-23: 🧹 Nitpick (assertive)

Remove trailing space

There's an unnecessary trailing space at the end of the file.

 });
-23
+
RDSExpoApp/constants/Colors.ts (1)

19-20: 🧹 Nitpick (assertive)

Remove trailing space

There's an unnecessary trailing space at the end of the file.

 };
-20
+
RDSExpoApp/app/(tabs)/index.tsx (1)

1-148: 🛠️ Refactor suggestion

Consider implementing comprehensive error handling and loading states

The authentication flow would benefit from:

  1. Loading indicators during async operations
  2. User-facing error messages
  3. Retry mechanisms for failed authentication attempts
  4. More comprehensive validation of the received tokens

These additions would significantly improve the reliability and user experience of the authentication process.

🧰 Tools
🪛 GitHub Check: build (18.x)

[warning] 100-100:
Inline style: { borderRadius: 12, marginTop: 20 }


[warning] 92-92:
Inline style: { borderRadius: 12 }


[failure] 73-73:
React Hook useEffect has missing dependencies: 'checkUserSession' and 'handleTokenFromUrl'. Either include them or remove the dependency array

🪛 GitHub Actions: Continous-Integeration

[error] 73-73: React Hook useEffect has missing dependencies: 'checkUserSession' and 'handleTokenFromUrl'. Either include them or remove the dependency array.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9e0903f and 4ff8c51.

⛔ Files ignored due to path filters (15)
  • RDSExpoApp/.yarn/install-state.gz is excluded by !**/.yarn/**, !**/*.gz
  • RDSExpoApp/android/app/src/main/res/drawable-hdpi/splashscreen_logo.png is excluded by !**/*.png
  • RDSExpoApp/android/app/src/main/res/drawable-mdpi/splashscreen_logo.png is excluded by !**/*.png
  • RDSExpoApp/android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png is excluded by !**/*.png
  • RDSExpoApp/android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png is excluded by !**/*.png
  • RDSExpoApp/android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png is excluded by !**/*.png
  • RDSExpoApp/android/gradle/wrapper/gradle-wrapper.jar is excluded by !**/*.jar
  • RDSExpoApp/assets/fonts/SpaceMono-Regular.ttf is excluded by !**/*.ttf
  • RDSExpoApp/assets/images/adaptive-icon.png is excluded by !**/*.png
  • RDSExpoApp/assets/images/favicon.png is excluded by !**/*.png
  • RDSExpoApp/assets/images/icon.png is excluded by !**/*.png
  • RDSExpoApp/assets/images/rdsLogo.png is excluded by !**/*.png
  • RDSExpoApp/assets/images/splash-icon.png is excluded by !**/*.png
  • RDSExpoApp/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (36)
  • RDSExpoApp/.gitignore (1 hunks)
  • RDSExpoApp/android/.gitignore (1 hunks)
  • RDSExpoApp/android/app/build.gradle (1 hunks)
  • RDSExpoApp/android/app/proguard-rules.pro (1 hunks)
  • RDSExpoApp/android/app/src/debug/AndroidManifest.xml (1 hunks)
  • RDSExpoApp/android/app/src/main/AndroidManifest.xml (1 hunks)
  • RDSExpoApp/android/app/src/main/java/com/abstrctdatyp/RDSExpoApp/MainActivity.kt (1 hunks)
  • RDSExpoApp/android/app/src/main/java/com/abstrctdatyp/RDSExpoApp/MainApplication.kt (1 hunks)
  • RDSExpoApp/android/app/src/main/res/drawable/ic_launcher_background.xml (1 hunks)
  • RDSExpoApp/android/app/src/main/res/drawable/rn_edit_text_material.xml (1 hunks)
  • RDSExpoApp/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml (1 hunks)
  • RDSExpoApp/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml (1 hunks)
  • RDSExpoApp/android/app/src/main/res/values-night/colors.xml (1 hunks)
  • RDSExpoApp/android/app/src/main/res/values/colors.xml (1 hunks)
  • RDSExpoApp/android/app/src/main/res/values/strings.xml (1 hunks)
  • RDSExpoApp/android/app/src/main/res/values/styles.xml (1 hunks)
  • RDSExpoApp/android/build.gradle (1 hunks)
  • RDSExpoApp/android/gradle.properties (1 hunks)
  • RDSExpoApp/android/gradle/wrapper/gradle-wrapper.properties (1 hunks)
  • RDSExpoApp/android/gradlew (1 hunks)
  • RDSExpoApp/android/gradlew.bat (1 hunks)
  • RDSExpoApp/android/settings.gradle (1 hunks)
  • RDSExpoApp/app.json (1 hunks)
  • RDSExpoApp/app/(tabs)/HomeScreen.tsx (1 hunks)
  • RDSExpoApp/app/(tabs)/NotifyScreen.tsx (1 hunks)
  • RDSExpoApp/app/(tabs)/ProfileScreen.tsx (1 hunks)
  • RDSExpoApp/app/(tabs)/_layout.tsx (1 hunks)
  • RDSExpoApp/app/(tabs)/index.tsx (1 hunks)
  • RDSExpoApp/app/_layout.tsx (1 hunks)
  • RDSExpoApp/assets/svgs/github_logo.js (1 hunks)
  • RDSExpoApp/constants/Colors.ts (1 hunks)
  • RDSExpoApp/constants/apiConstant/AuthApi.ts (1 hunks)
  • RDSExpoApp/constants/apiConstant/BaseUrl.ts (1 hunks)
  • RDSExpoApp/package.json (1 hunks)
  • RDSExpoApp/tsconfig.json (1 hunks)
  • metro.config.js (0 hunks)
💤 Files with no reviewable changes (1)
  • metro.config.js
🧰 Additional context used
🧬 Code Definitions (1)
RDSExpoApp/constants/apiConstant/AuthApi.ts (1)
RDSExpoApp/constants/apiConstant/BaseUrl.ts (1)
  • STAGING_BASE_URL (3-3)
🪛 GitHub Check: build (18.x)
RDSExpoApp/app/(tabs)/_layout.tsx

[warning] 52-52:
Inline style: { marginBottom: -3 }


[warning] 47-47:
Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state (https://reactjs.org/docs/reconciliation.html#elements-of-different-types). Instead, move this component definition out of the parent component “TabLayout” and pass data as props. If you want to allow component creation in props, set allowAsProps option to true


[warning] 36-36:
Inline style: { marginBottom: -3 }


[warning] 31-31:
Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state (https://reactjs.org/docs/reconciliation.html#elements-of-different-types). Instead, move this component definition out of the parent component “TabLayout” and pass data as props. If you want to allow component creation in props, set allowAsProps option to true

RDSExpoApp/app/(tabs)/index.tsx

[warning] 100-100:
Inline style: { borderRadius: 12, marginTop: 20 }


[warning] 92-92:
Inline style: { borderRadius: 12 }


[failure] 73-73:
React Hook useEffect has missing dependencies: 'checkUserSession' and 'handleTokenFromUrl'. Either include them or remove the dependency array

🪛 GitHub Actions: Continous-Integeration
RDSExpoApp/app/(tabs)/_layout.tsx

[warning] 31-31: Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state. Instead, move this component definition out of the parent component 'TabLayout' and pass data as props.


[warning] 36-36: Inline style: { marginBottom: -3 }


[warning] 47-47: Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state. Instead, move this component definition out of the parent component 'TabLayout' and pass data as props.


[warning] 52-52: Inline style: { marginBottom: -3 }


[warning] 63-63: Do not define components during render. React will see a new component type on every render and destroy the entire subtree’s DOM nodes and state. Instead, move this component definition out of the parent component 'TabLayout' and pass data as props.


[warning] 68-68: Inline style: { marginBottom: -3 }

RDSExpoApp/app/(tabs)/index.tsx

[error] 73-73: React Hook useEffect has missing dependencies: 'checkUserSession' and 'handleTokenFromUrl'. Either include them or remove the dependency array.

🔇 Additional comments (65)
RDSExpoApp/assets/svgs/github_logo.js (2)

1-2: Good choice of using react-native-svg for SVG rendering.

Using react-native-svg is the recommended approach for rendering SVGs in React Native applications, which aligns well with the Expo migration objective.


20-20: LGTM - Clean export pattern.

The default export of the component follows the standard React pattern and makes the component easy to import.

RDSExpoApp/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml (1)

1-5: Adaptive Icon XML is Configured Correctly: The adaptive icon is well defined with clear background and foreground references. Please ensure that the resource names (@color/iconBackground and @mipmap/ic_launcher_foreground) are defined elsewhere in the project.

RDSExpoApp/android/app/src/main/res/drawable/ic_launcher_background.xml (1)

1-6: Layer-list Drawable Defined Properly: The file correctly creates a composite drawable by combining a solid color from @color/splashscreen_background with a centered bitmap (@drawable/splashscreen_logo). Verify that these referenced resources exist and meet the design requirements.

RDSExpoApp/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml (1)

1-5: Round Adaptive Icon XML is Correct: The round adaptive icon mirrors the standard adaptive icon structure, correctly referencing the background and foreground resources. Confirm that @color/iconBackground and @mipmap/ic_launcher_foreground are available in your project resources.

RDSExpoApp/android/.gitignore (1)

1-17: Comprehensive .gitignore for Android: The .gitignore file appropriately excludes common OS-specific files, Android/IntelliJ build artifacts, local configuration files, and bundle artifacts. This should help keep the repository clean from unnecessary files.

RDSExpoApp/.gitignore (1)

1-37: Well-Structured .gitignore File
The file is comprehensive and clearly lists the files, directories, and file patterns that should be ignored. It covers essential dependency folders (like node_modules/), Expo artifacts, native build files, debugging logs, macOS system files, and TypeScript build outputs. This will help keep the repository clean and reduce clutter.

RDSExpoApp/tsconfig.json (1)

1-20: Solid TypeScript Configuration
The tsconfig.json correctly extends Expo’s base configuration and sets strict compiler options along with an appropriate path alias (@/*). The inclusion of all relevant TypeScript and type definition files ensures that the project is well-covered during compilation.

RDSExpoApp/android/build.gradle (1)

1-42: Robust Android Gradle Configuration
The Gradle file is well-structured and aligns with the requirements for a React Native Expo project on Android. It correctly establishes the buildscript environment with externalized properties and includes the necessary repositories and dependencies. A couple of points for consideration:

  • Versioning: The dependency declarations for the Android Gradle plugin, React Native Gradle plugin, and Kotlin plugin do not include explicit version numbers. If these versions are managed elsewhere (e.g., via a gradle wrapper or external properties), this approach is acceptable; otherwise, adding version numbers might help ensure build consistency.
  • Dynamic Node Resolution: The use of dynamic resolution (via Node commands) in the repository URLs is clever but can be fragile in environments where Node isn’t available or configured in the system PATH. Please verify this works consistently across all build environments.
RDSExpoApp/android/app/proguard-rules.pro (1)

1-15: Effective ProGuard Rules Setup
This ProGuard configuration file appropriately preserves the necessary classes for react-native-reanimated and React Native TurboModules, ensuring that these critical packages are not obfuscated or stripped during the build process. This setup is in line with the requirements for a React Native Expo Android project. If additional libraries are integrated in the future, remember to review and potentially extend these rules accordingly.

RDSExpoApp/android/app/src/debug/AndroidManifest.xml (1)

1-8: Review Note: Validate Debug Manifest Configuration
The manifest correctly declares the SYSTEM_ALERT_WINDOW permission and sets cleartext traffic for the debug build. Verify that the use of cleartext traffic (via android:usesCleartextTraffic="true") is intended only for development and that a more secure configuration is enforced in production.

RDSExpoApp/android/app/src/main/res/values/styles.xml (1)

1-19: Review Note: Ensure Consistent Theming
The styles resource defines key themes including AppTheme, ResetEditText, and Theme.App.SplashScreen consistently. Please double-check that hard-coded values (e.g., #ffffff for the status bar) fit your design guidelines, including potential support for dark mode if needed.

RDSExpoApp/android/gradle/wrapper/gradle-wrapper.properties (1)

1-7: Review Note: Gradle Wrapper Settings
The gradle-wrapper properties are set to use Gradle version 8.10.2 with a 10-second network timeout. Ensure that this version is compatible with your React Native/Expo toolchain and that these settings meet your build environment requirements.

RDSExpoApp/android/app/src/main/res/values/colors.xml (1)

1-6: Review Note: Color Resource Definitions
The colors resource file neatly centralizes key color definitions. Confirm that the chosen colors (e.g., using white for splashscreen_background and colorPrimaryDark) align with your app’s design requirements.

RDSExpoApp/android/settings.gradle (1)

1-39:

Details

❓ Verification inconclusive

Review Note: Dynamic Gradle Configuration
This settings file leverages dynamic Node.js command executions to resolve paths for the React Native Gradle plugin and Expo modules. While this approach streamlines configuration, please ensure:

  • These commands consistently execute across different environments (local, CI, etc.).
  • Consideration for error handling or fallback strategies if Node is unavailable or if resolution fails.
    Additionally, verify that the autolinking commands and dependency resolution management integrate seamlessly with the rest of the Android build process.

Action Required: Verify Robustness of Dynamic Node Execution in Gradle Settings

The settings file employs dynamic Node.js command executions to resolve paths for the React Native Gradle plugin and Expo modules. Please verify the following:

  • That these Node-based commands execute consistently across environments (local, CI, etc.).
  • That any potential failures (e.g., if Node isn’t available or a resolution fails) are gracefully handled—consider adding explicit error handling or fallback strategies.
  • That the autolinking command and dependency resolution management integrate correctly within the overall Android build process.
RDSExpoApp/android/app/src/main/AndroidManifest.xml (10)

1-7: Permissions and Manifest Declaration are Correct.
All the necessary permissions (INTERNET, external storage, etc.) are declared properly.


8-14: Queries Block is Implemented as Expected.
The intent query for the HTTPS scheme is correctly specified. Verify later if additional hosts might be needed.


16-23: Application Element is Well Configured.
The application element includes appropriate meta-data (Expo update flags), theme, icon, and RTL support.


29-36: MainActivity Declaration is Comprehensive.
Configuration settings like launch mode, configChanges, windowSoftInputMode, and portrait orientation properly address the requirements of a React Native/Expo app.


38-41: Launcher Intent Filter is Standard.
Declaring ACTION_MAIN with CATEGORY_LAUNCHER ensures proper app startup.


43-49: OAuth Redirect Filter Review.
The intent filter intended for OAuth redirection uses the custom scheme "rdsapp" and host "ProfileScreen". Please verify that this matches the deep linking and routing setup in your Expo configuration.


51-57: Additional Deep-Link Filter for 'rdsapp' Scheme.
The intent filter capturing all "rdsapp" links (without host restrictions) supports development scenarios.


70-78: AutoVerify Set to False for 'realdevsquad.com'.
Intent filter for "realdevsquad.com" is configured with autoVerify="false". Confirm that this behavior is desired in your migration context.


80-88: AutoVerify Intent Filter for 'rdsapp.netlify.app' is Configured Properly.
Enabling autoVerify for "rdsapp.netlify.app" seems to be in line with domain verification strategies.


91-93: Manifest Structure Closes Correctly.
The closing tags are properly formatted and the overall structure adheres to standard Android practices.

RDSExpoApp/android/app/src/main/res/drawable/rn_edit_text_material.xml (4)

1-15: XML Declaration and License Block are Standard.
The file begins with the XML declaration and includes the complete Apache 2.0 license header.


16-21: Inset Element is Defined Correctly.
The inset element uses dimension resources appropriately to set padding values.


23-36: Selector Configuration Addresses Known Issue.
The commented-out item explains the NullPointerException issue well. The included items (for disabled and default states) should cover the drawable state requirements.


37-38: XML Document Closes Properly.
The closing tag maintains the document’s integrity.

RDSExpoApp/android/app/src/main/res/values/strings.xml (1)

1-6: String Resources are Appropriately Defined.
The strings for the application name and splash screen configurations (including non-translatable attributes) are correctly set.

RDSExpoApp/android/app/build.gradle (6)

1-4: Plugins are Applied Correctly.
The Android, Kotlin, and React Native plugins are included as required.


5-5: Project Root Calculation is Sound.
The computation of the project root using Groovy’s file APIs seems robust for the intended directory structure.


11-63: Comprehensive React Native Configuration Block.
The use of node commands to resolve paths (entry file, reactNativeDir, hermesCommand, and codegenDir) reflects common patterns in Expo projects. Consider adding error handling if any of these command executions fail.


83-127: Android Block is Configured Standardly.
SDK versions, namespace, applicationId, and build types are defined as expected.
Note: The release build currently uses the debug signing configuration (line 112). Make sure to update this before production.


129-147: Dynamic Packaging Options are Creatively Handled.
The logic for splitting and trimming packaging options from Gradle properties is clever. Please verify that it behaves reliably across different environments and configurations.


149-177: Dependencies Block Manages Optional Features Well.
Conditional inclusion for GIF and WebP support—and the choice between Hermes and JavaScriptCore—are handled properly based on project properties.

RDSExpoApp/android/gradlew (9)

1-20: Gradle Wrapper Script Header is Standard.
The shebang, licensing information, and SPDX identifier are in line with the Gradle wrapper conventions.


67-83: Robust APP_HOME Resolution Logic.
The loop correctly handles daisy-chained symbolic links to set the application path reliably.


85-91: APP_HOME Canonicalization is Handled Properly.
Using cd -P and capturing the present working directory ensures a correct absolute path; this is a standard and dependable technique.


95-104: Error Handling Functions are Well Defined.
The custom warn and die functions provide clear and user-friendly error messages, which is good for shell scripting.


121-144: Java Command Resolution is Handled Carefully.
The script checks for the presence of JAVA_HOME and correctly distinguishes IBM’s JDK layout. This fallback mechanism is standard practice.


146-163: File Descriptor Limit Adjustment is Logical.
Using ulimit to query and set file descriptor limits is a good practice. Ensure that the chosen MAX_FD value is appropriate on all target platforms.


214-218: Java Command Argument Assembly is Clear and Secure.
The aggregation of JVM options, classpath, main class, and command-line arguments is well done, ensuring proper quoting and sequence.


220-224: xargs Availability Check is Prudent.
Confirming that xargs is available helps avoid runtime errors during argument parsing.


252-253: Final Execution is Standard.
The script’s final exec call to invoke the resolved Java command with all arguments is standard for Gradle wrapper scripts.

RDSExpoApp/package.json (2)

1-46: Well-configured package.json for Expo React Native app.

The package.json is properly configured with appropriate dependencies for an Expo React Native application. The use of specific versioning for packages helps ensure compatibility.


16-34:

Details

✅ Verification successful

Verify AsyncStorage version compatibility.

The AsyncStorage version (1.23.1) is quite recent. Make sure it's fully compatible with the rest of your dependencies.


🏁 Script executed:

#!/bin/bash
# Check compatibility of AsyncStorage version with the React Native version
echo "Checking compatibility of @react-native-async-storage/async-storage 1.23.1 with React Native 0.76.7"
npm view @react-native-async-storage/async-storage@1.23.1 peerDependencies

Length of output: 331


AsyncStorage Compatibility Confirmed
The output shows that @react-native-async-storage/async-storage@1.23.1 specifies a peer dependency constraint of 'react-native': '^0.0.0-0 || >=0.60 <1.0'. Since the current React Native version is 0.76.7—well within the supported range—no further action is needed for this dependency.

RDSExpoApp/android/gradlew.bat (1)

1-95: Standard Gradle wrapper file is correctly included.

This is a standard Gradle wrapper batch script for Windows environments. It's properly configured with adequate error handling and execution setup.

RDSExpoApp/android/app/src/main/java/com/abstrctdatyp/RDSExpoApp/MainActivity.kt (3)

36-45: New Architecture configuration is correct.

The ReactActivityDelegate is properly configured with the new architecture flag and fabricEnabled for Fabric renderer support.


52-64: Good back button behavior implementation.

The back button behavior is correctly customized to match Android S (API 31+) behavior on older versions, maintaining consistent UX across different Android versions.


14-24:

Details

❓ Verification inconclusive

Check commented theme configuration.

There's a commented-out theme configuration on line 19. Verify if this is intentional or if the theme should be properly set for the splash screen.


🏁 Script executed:

#!/bin/bash
# Check if AppTheme is defined in the styles.xml file
if [ -f "RDSExpoApp/android/app/src/main/res/values/styles.xml" ]; then
  echo "Checking for AppTheme in styles.xml"
  cat "RDSExpoApp/android/app/src/main/res/values/styles.xml" | grep -A 10 "AppTheme"
else
  echo "styles.xml not found to verify AppTheme"
fi

Length of output: 955


Action: Verify the theme configuration in MainActivity

We confirmed that the AppTheme is properly defined in styles.xml. However, the call to setTheme(R.style.AppTheme) remains commented out in MainActivity.kt. Please verify if this was an intentional decision—perhaps because the expo-splash-screen integration now handles the theme automatically—or if the theme needs to be explicitly applied during onCreate. If explicit theming is required for proper splash screen behavior, consider uncommenting the line. Otherwise, removing the commented code could help avoid confusion.

RDSExpoApp/android/gradle.properties (4)

10-13: Appropriate memory settings for Gradle daemon.

The JVM memory settings are properly increased for better build performance, which is especially important for larger React Native projects.


40-42: Hermes is properly enabled.

Hermes JS engine is enabled, which is good for performance and memory usage in React Native applications.


44-50: Image format support is well configured.

Support for GIF and static WebP is enabled, while animated WebP is disabled (which is appropriate due to iOS limitations).


33-38:

Details

❓ Verification inconclusive

New Architecture is enabled by default.

The new architecture is enabled by default, which is forward-looking but may introduce some compatibility issues with certain native modules that haven't been updated yet.


🏁 Script executed:

#!/bin/bash
# Check for dependencies that might have issues with the new architecture
if [ -f "RDSExpoApp/package.json" ]; then
  echo "Checking native dependencies that might need verification with new architecture:"
  cat "RDSExpoApp/package.json" | grep -A 20 "dependencies" | grep "react-native-" | cut -d'"' -f2
else
  echo "package.json not found to verify native dependencies"
fi

Length of output: 435


Action Required: Review Native Module Compatibility for New Architecture

The configuration in RDSExpoApp/android/gradle.properties now sets newArchEnabled=true by default to support TurboModules and Fabric rendering. This forward-looking change is great for enabling future features, but it may lead to compatibility issues with certain native modules. Notably, your package.json shows dependencies such as:

  • @react-native-async-storage/async-storage
  • react-native-reanimated
  • react-native-safe-area-context
  • react-native-screens
  • react-native-web

Please verify that these dependencies have been tested and confirmed to function correctly under the new architecture. If any of these native modules exhibit issues, you might need to delay enabling this setting or apply patch updates where available.

RDSExpoApp/android/app/src/main/java/com/abstrctdatyp/RDSExpoApp/MainApplication.kt (5)

21-38: LGTM: ReactNativeHost implementation is correctly configured for Expo.

The implementation uses ReactNativeHostWrapper from Expo modules and properly configures the JavaScript entry point to .expo/.virtual-metro-entry, which is required for Expo applications. The packages setup also allows for manual additions if needed.


40-41: LGTM: ReactHost implementation uses the recommended approach.

The implementation correctly uses ReactNativeHostWrapper.createReactHost() to create a React host from the reactNativeHost, which is the proper pattern for Expo applications.


43-51: LGTM: Application lifecycle initialization is properly implemented.

The onCreate() method correctly initializes SoLoader, conditionally loads the native entry point for the new architecture, and properly notifies Expo's lifecycle dispatcher.


53-56: LGTM: Configuration changes are handled appropriately.

The onConfigurationChanged() method properly calls the superclass implementation and notifies Expo's lifecycle dispatcher, which is necessary for Expo to handle configuration changes correctly.


31-31:

Details

❓ Verification inconclusive

Verify that the JS main module path is correct.

The JS main module name is set to .expo/.virtual-metro-entry. Confirm that this path aligns with the Expo configuration in your project, as incorrect paths can lead to app launch failures.


🏁 Script executed:

#!/bin/bash
# Check if the entry file exists in the project
if [ -d ".expo" ]; then
  echo "Checking .expo directory structure..."
  find .expo -name ".virtual-metro-entry*" -type f | sort
else
  echo ".expo directory not found at the root level"
  # Try to find it elsewhere in the project
  find . -name ".expo" -type d | xargs -I{} find {} -name ".virtual-metro-entry*" -type f
fi

# Check the app.json or app.config.js for related configuration
if [ -f "app.json" ]; then
  echo "Checking app.json for entryPoint configuration..."
  grep -A 3 "entryPoint" app.json
fi

if [ -f "app.config.js" ]; then
  echo "Checking app.config.js for entryPoint configuration..."
  grep -A 3 "entryPoint" app.config.js
fi

# Look for metro.config.js
if [ -f "metro.config.js" ]; then
  echo "Checking metro.config.js for relevant configuration..."
  cat metro.config.js
fi

Length of output: 426


Action: Confirm the JS main module path configuration.

After reviewing the project structure and configuration, the script output indicates that the .expo directory wasn’t found at the repository root and no .virtual-metro-entry file was detected. Additionally, the Expo configuration (e.g. via entryPoint in app.json) doesn’t appear to override the default. Please verify that your project either generates or relocates the expected .expo/.virtual-metro-entry file at runtime. If your Expo setup uses a custom configuration or build process that handles this differently, ensure that the configuration aligns with the expected module path.

  • Confirm that the build process generates the .expo folder (and the .virtual-metro-entry file) in the correct location.
  • Double-check the Expo configuration (e.g. in app.json) to ensure there’s no conflicting entryPoint setting.
RDSExpoApp/app/_layout.tsx (1)

19-36: LGTM: Well-structured component with proper font loading and error handling

The RootLayout component has good error handling for font loading and properly manages the splash screen. The use of useEffect hooks to handle errors and hide the splash screen is well implemented.

RDSExpoApp/app/(tabs)/index.tsx (4)

15-20: LGTM - Well-implemented URL builder utility

The buildUrl function correctly handles URL construction with query parameters, properly encoding parameter values.


75-79: LGTM - handleSignIn function implementation

The implementation correctly opens the GitHub authentication URL and handles potential errors.


106-147: LGTM - Well-organized StyleSheet

The StyleSheet is well-organized with clear naming conventions. Consider adding the missing styles for the buttons as mentioned in the previous comment.


91-94:

Details

❓ Verification inconclusive

Differentiate between GitHub and Web sign-in functionalities

Both buttons currently use the same handleSignIn function, which only opens the GitHub authentication URL. If they're meant to have different behaviors, they should use different handler functions.

Also, move inline styles to the StyleSheet for consistency:

- <TouchableOpacity style={[styles.button, { borderRadius: 12 }]} onPress={handleSignIn}>
+ <TouchableOpacity style={[styles.button, styles.githubButton]} onPress={handleSignIn}>
  <FontAwesome name="github" size={24} color="#000" style={styles.icon} />
  <Text style={styles.buttonText}>GitHub SignIn</Text>
</TouchableOpacity>

- <TouchableOpacity style={[styles.button, { borderRadius: 12, marginTop: 20 }]} onPress={handleSignIn}>
+ <TouchableOpacity style={[styles.button, styles.webButton]} onPress={handleWebSignIn}>
  <FontAwesome name="globe" size={24} color="#000" style={styles.icon} />
  <Text style={styles.buttonText}>Web SignIn</Text>
</TouchableOpacity>

// And in the StyleSheet:
+ githubButton: {
+   borderRadius: 12,
+ },
+ webButton: {
+   borderRadius: 12,
+   marginTop: 20,
+ },

Also applies to: 96-99


🏁 Script executed:

#!/bin/bash
# Check if there are different sign-in methods implemented
echo "Checking for web sign-in implementation..."
rg -A 5 "webSignIn" RDSExpoApp/

Length of output: 126


Action Required: Confirm Distinct Sign-In Behavior & Style Consistency

The current implementation for the GitHub and Web sign-in buttons still uses the same handleSignIn function. Our search did not locate a separate handler (e.g., handleWebSignIn) or any alternative implementation for the Web sign-in functionality, which may indicate that differentiation hasn't been implemented yet. If distinct behaviors for GitHub and Web sign-in are intended, please ensure that:

  • Behavior:

    • The GitHub button continues to use handleSignIn (or an appropriately named GitHub-specific function).
    • A separate handler, such as handleWebSignIn, is implemented and assigned to the Web sign-in button.
  • Styling:

    • Move the inline style properties (e.g., borderRadius, marginTop) into the component’s StyleSheet (as shown in the provided diff snippet) to maintain consistency across the codebase.

Please manually verify whether the Web sign-in functionality should have a unique handler and update the implementation accordingly.

🧰 Tools
🪛 GitHub Check: build (18.x)

[warning] 92-92:
Inline style: { borderRadius: 12 }

Comment on lines +3 to +19
const GithubSvg = (props) => (
<Svg
xmlns="http://www.w3.org/2000/svg"
xmlSpace="preserve"
viewBox="0 0 32 32"
{...props}
>
<Path
fill="#1A1718"
d="M16 3.006C8.835 3.006 3.007 8.835 3.007 16S8.836 28.994 16 28.994 28.994 23.165 28.994 16 23.165 3.006 16 3.006zm1.953 15.825c.319.276.566 1.251.566 1.699v3.964h-4.527s.006-1.344 0-2.265c-3.099.667-3.964-1.699-3.964-1.699-.566-1.132-1.132-1.699-1.132-1.699-1.132-.673 0-.566 0-.566 1.132 0 1.699 1.132 1.699 1.132.994 1.687 2.762 1.416 3.397 1.132 0-.566.248-1.422.566-1.699-2.473-.279-4.532-1.699-4.532-4.53 0-2.831.568-3.397 1.135-3.964-.114-.279-.588-1.311.018-2.831 0 0 1.113 0 2.245 1.699.561-.561 2.265-.566 2.832-.566.565 0 2.269.005 2.83.566 1.132-1.699 2.248-1.699 2.248-1.699.605 1.52.132 2.552.017 2.831.566.566 1.132 1.132 1.132 3.964s-2.056 4.253-4.53 4.531z"
/>
<Path
fill="#1A1718"
d="M16 0C7.163 0 0 7.163 0 16s7.164 16 16 16c8.837 0 16-7.163 16-16S24.837 0 16 0zm0 29.493C8.548 29.493 2.507 23.452 2.507 16S8.548 2.506 16 2.506c7.453 0 13.494 6.041 13.494 13.493 0 7.453-6.042 13.494-13.494 13.494z"
/>
</Svg>
);
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider enhancing the SVG component with accessibility and customization options.

The GitHub logo SVG implementation is clean and follows React functional component patterns. However, consider the following improvements:

  1. Add accessibility attributes for screen readers
  2. Allow customization of the fill color through props instead of hardcoding
-const GithubSvg = (props) => (
+const GithubSvg = ({ fill = '#1A1718', ...props }) => (
  <Svg
    xmlns="http://www.w3.org/2000/svg"
    xmlSpace="preserve"
    viewBox="0 0 32 32"
+   aria-label="GitHub logo"
+   role="img"
    {...props}
  >
    <Path
-     fill="#1A1718"
+     fill={fill}
      d="M16 3.006C8.835 3.006 3.007 8.835 3.007 16S8.836 28.994 16 28.994 28.994 23.165 28.994 16 23.165 3.006 16 3.006zm1.953 15.825c.319.276.566 1.251.566 1.699v3.964h-4.527s.006-1.344 0-2.265c-3.099.667-3.964-1.699-3.964-1.699-.566-1.132-1.132-1.699-1.132-1.699-1.132-.673 0-.566 0-.566 1.132 0 1.699 1.132 1.699 1.132.994 1.687 2.762 1.416 3.397 1.132 0-.566.248-1.422.566-1.699-2.473-.279-4.532-1.699-4.532-4.53 0-2.831.568-3.397 1.135-3.964-.114-.279-.588-1.311.018-2.831 0 0 1.113 0 2.245 1.699.561-.561 2.265-.566 2.832-.566.565 0 2.269.005 2.83.566 1.132-1.699 2.248-1.699 2.248-1.699.605 1.52.132 2.552.017 2.831.566.566 1.132 1.132 1.132 3.964s-2.056 4.253-4.53 4.531z"
    />
    <Path
-     fill="#1A1718"
+     fill={fill}
      d="M16 0C7.163 0 0 7.163 0 16s7.164 16 16 16c8.837 0 16-7.163 16-16S24.837 0 16 0zm0 29.493C8.548 29.493 2.507 23.452 2.507 16S8.548 2.506 16 2.506c7.453 0 13.494 6.041 13.494 13.493 0 7.453-6.042 13.494-13.494 13.494z"
    />
  </Svg>
);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const GithubSvg = (props) => (
<Svg
xmlns="http://www.w3.org/2000/svg"
xmlSpace="preserve"
viewBox="0 0 32 32"
{...props}
>
<Path
fill="#1A1718"
d="M16 3.006C8.835 3.006 3.007 8.835 3.007 16S8.836 28.994 16 28.994 28.994 23.165 28.994 16 23.165 3.006 16 3.006zm1.953 15.825c.319.276.566 1.251.566 1.699v3.964h-4.527s.006-1.344 0-2.265c-3.099.667-3.964-1.699-3.964-1.699-.566-1.132-1.132-1.699-1.132-1.699-1.132-.673 0-.566 0-.566 1.132 0 1.699 1.132 1.699 1.132.994 1.687 2.762 1.416 3.397 1.132 0-.566.248-1.422.566-1.699-2.473-.279-4.532-1.699-4.532-4.53 0-2.831.568-3.397 1.135-3.964-.114-.279-.588-1.311.018-2.831 0 0 1.113 0 2.245 1.699.561-.561 2.265-.566 2.832-.566.565 0 2.269.005 2.83.566 1.132-1.699 2.248-1.699 2.248-1.699.605 1.52.132 2.552.017 2.831.566.566 1.132 1.132 1.132 3.964s-2.056 4.253-4.53 4.531z"
/>
<Path
fill="#1A1718"
d="M16 0C7.163 0 0 7.163 0 16s7.164 16 16 16c8.837 0 16-7.163 16-16S24.837 0 16 0zm0 29.493C8.548 29.493 2.507 23.452 2.507 16S8.548 2.506 16 2.506c7.453 0 13.494 6.041 13.494 13.493 0 7.453-6.042 13.494-13.494 13.494z"
/>
</Svg>
);
const GithubSvg = ({ fill = '#1A1718', ...props }) => (
<Svg
xmlns="http://www.w3.org/2000/svg"
xmlSpace="preserve"
viewBox="0 0 32 32"
aria-label="GitHub logo"
role="img"
{...props}
>
<Path
fill={fill}
d="M16 3.006C8.835 3.006 3.007 8.835 3.007 16S8.836 28.994 16 28.994 28.994 23.165 28.994 16 23.165 3.006 16 3.006zm1.953 15.825c.319.276.566 1.251.566 1.699v3.964h-4.527s.006-1.344 0-2.265c-3.099.667-3.964-1.699-3.964-1.699-.566-1.132-1.132-1.699-1.132-1.699-1.132-.673 0-.566 0-.566 1.132 0 1.699 1.132 1.699 1.132.994 1.687 2.762 1.416 3.397 1.132 0-.566.248-1.422.566-1.699-2.473-.279-4.532-1.699-4.532-4.53 0-2.831.568-3.397 1.135-3.964-.114-.279-.588-1.311.018-2.831 0 0 1.113 0 2.245 1.699.561-.561 2.265-.566 2.832-.566.565 0 2.269.005 2.83.566 1.132-1.699 2.248-1.699 2.248-1.699.605 1.52.132 2.552.017 2.831.566.566 1.132 1.132 1.132 3.964s-2.056 4.253-4.53 4.531z"
/>
<Path
fill={fill}
d="M16 0C7.163 0 0 7.163 0 16s7.164 16 16 16c8.837 0 16-7.163 16-16S24.837 0 16 0zm0 29.493C8.548 29.493 2.507 23.452 2.507 16S8.548 2.506 16 2.506c7.453 0 13.494 6.041 13.494 13.493 0 7.453-6.042 13.494-13.494 13.494z"
/>
</Svg>
);

@@ -0,0 +1 @@
<resources/> No newline at end of file
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Empty Night Mode Colors Resource: This file currently only contains an empty <resources/> element. If the intention is to provide a placeholder for dark theme colors, it might be useful to add a comment inside the resource tag or placeholders indicating future additions.

Comment on lines +1 to +42
{
"expo": {
"name": "RDSExpoApp",
"slug": "RDSExpoApp",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/images/icon.png",
"scheme": "rdsapp",
"userInterfaceStyle": "automatic",
"newArchEnabled": true,
"splash": {
"image": "./assets/images/splash-icon.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"ios": {
"supportsTablet": true
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/images/adaptive-icon.png",
"backgroundColor": "#ffffff"
},
"package": "com.abstrctdatyp.RDSExpoApp"
},
"web": {
"bundler": "metro",
"output": "static",
"favicon": "./assets/images/favicon.png"
},
"plugins": [
"expo-router"
],
"experiments": {
"typedRoutes": true
},
"extra": {
"GITHUB_CLIENT_ID": "Ov23lidvROsX75m5UoNm",
"GITHUB_AUTHORIZATION_CALLBACK_URL": "http://localhost:3000/auth/github/callback"
}
}
} No newline at end of file
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Comprehensive Expo App Configuration
The app.json file is well-constructed, encapsulating all crucial aspects of the Expo application configuration. It specifies the app’s name, schema, splash screen, platform-specific settings, and even experimental features like typed routes. One suggestion: consider externalizing sensitive or environment-specific values (such as GITHUB_CLIENT_ID and callback URLs) into environment variables to enhance security and flexibility across different deployment contexts.

Comment on lines +59 to +68
<intent-filter >
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data
android:scheme="https"
android:host="www.realdevsquad.com/" />
</intent-filter>
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Host Value Format Observation.
The intent filter for the HTTPS scheme uses android:host="www.realdevsquad.com/" (line 67) with a trailing slash. Typically, host values should omit the trailing slash. Please confirm if this is intentional.

Comment on lines +245 to +251
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'

Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Advanced Argument Parsing via eval and sed.
The use of eval on processed arguments addresses shell metacharacter concerns. While functional, this approach can be fragile on edge cases—thorough testing is advisable.

Comment on lines +9 to +17
const handleLogout = async () => {
try {
await AsyncStorage.removeItem('github_token');
console.log('User logged out');
router.replace('/');
} catch (error) {
console.error('Error logging out', error);
}
};
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Improve user feedback during logout.

Currently, there's no visual feedback to the user during the logout process, and errors are only logged to the console.

+import { StyleSheet, Text, TouchableOpacity, View, Alert, ActivityIndicator } from 'react-native';
 
 export default function ProfileScreen() {
   const router = useRouter();
+  const [isLoggingOut, setIsLoggingOut] = useState(false);
 
   const handleLogout = async () => {
+    setIsLoggingOut(true);
     try {
-      await AsyncStorage.removeItem('github_token');
-      console.log('User logged out');
-      router.replace('/');
+      // Consider adding a confirmation dialog
+      const confirmLogout = await new Promise((resolve) => {
+        Alert.alert(
+          "Confirm Logout",
+          "Are you sure you want to log out?",
+          [
+            { text: "Cancel", onPress: () => resolve(false), style: "cancel" },
+            { text: "Logout", onPress: () => resolve(true) }
+          ]
+        );
+      });
+      
+      if (confirmLogout) {
+        await AsyncStorage.removeItem('github_token');
+        console.log('User logged out');
+        router.replace('/');
+      }
     } catch (error) {
       console.error('Error logging out', error);
+      Alert.alert("Logout Failed", "There was a problem logging you out. Please try again.");
+    } finally {
+      setIsLoggingOut(false);
     }
   };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleLogout = async () => {
try {
await AsyncStorage.removeItem('github_token');
console.log('User logged out');
router.replace('/');
} catch (error) {
console.error('Error logging out', error);
}
};
import React, { useState } from 'react';
import { StyleSheet, Text, TouchableOpacity, View, Alert, ActivityIndicator } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useRouter } from 'expo-router';
export default function ProfileScreen() {
const router = useRouter();
const [isLoggingOut, setIsLoggingOut] = useState(false);
const handleLogout = async () => {
setIsLoggingOut(true);
try {
// Consider adding a confirmation dialog
const confirmLogout = await new Promise((resolve) => {
Alert.alert(
"Confirm Logout",
"Are you sure you want to log out?",
[
{ text: "Cancel", onPress: () => resolve(false), style: "cancel" },
{ text: "Logout", onPress: () => resolve(true) }
]
);
});
if (confirmLogout) {
await AsyncStorage.removeItem('github_token');
console.log('User logged out');
router.replace('/');
}
} catch (error) {
console.error('Error logging out', error);
Alert.alert("Logout Failed", "There was a problem logging you out. Please try again.");
} finally {
setIsLoggingOut(false);
}
};
return (
<View style={styles.container}>
{isLoggingOut ? (
<ActivityIndicator size="large" color="#0000ff" />
) : (
<TouchableOpacity onPress={handleLogout} style={styles.button}>
<Text style={styles.buttonText}>Logout</Text>
</TouchableOpacity>
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
button: {
backgroundColor: '#2089dc',
padding: 12,
borderRadius: 8,
},
buttonText: {
color: '#ffffff',
fontWeight: 'bold',
},
});

Comment on lines +25 to +31
const queryParams = {
sourceUtm: 'rds-mobile-app',
redirectURL: 'rdsapp://auth',
};

const githubAuthUrl = buildUrl(AuthApi.GITHUB_AUTH_API, queryParams);

Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider more descriptive variable naming

While the implementation is correct, consider renaming sourceUtm to something more descriptive like source or utmSource. Also, it might be helpful to add a comment explaining the purpose of the redirect URL format rdsapp://auth.

Comment on lines +40 to +52
const handleTokenFromUrl = async (url: string) => {
try {
const urlObj = new URL(url);
const token = urlObj.searchParams.get('token');
if (token) {
await AsyncStorage.setItem('github_token', token);
console.log('Token stored:', token);
router.replace('/HomeScreen');
}
} catch (error) {
console.error('Error processing deep link', error);
}
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid logging sensitive data and improve error handling

The token is being logged to the console, which could be a security concern. Also, consider adding more specific error handling and user feedback.

const handleTokenFromUrl = async (url: string) => {
  try {
    const urlObj = new URL(url);
    const token = urlObj.searchParams.get('token');
    if (token) {
      await AsyncStorage.setItem('github_token', token);
-     console.log('Token stored:', token);
+     console.log('Token stored successfully');
      router.replace('/HomeScreen');
+   } else {
+     console.error('No token found in URL');
+     // Consider showing an error message to the user
    }
  } catch (error) {
    console.error('Error processing deep link', error);
+   // Consider showing an error message to the user
  }
};
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleTokenFromUrl = async (url: string) => {
try {
const urlObj = new URL(url);
const token = urlObj.searchParams.get('token');
if (token) {
await AsyncStorage.setItem('github_token', token);
console.log('Token stored:', token);
router.replace('/HomeScreen');
}
} catch (error) {
console.error('Error processing deep link', error);
}
};
const handleTokenFromUrl = async (url: string) => {
try {
const urlObj = new URL(url);
const token = urlObj.searchParams.get('token');
if (token) {
await AsyncStorage.setItem('github_token', token);
console.log('Token stored successfully');
router.replace('/HomeScreen');
} else {
console.error('No token found in URL');
// Consider showing an error message to the user
}
} catch (error) {
console.error('Error processing deep link', error);
// Consider showing an error message to the user
}
};

Comment on lines +54 to +73
useEffect(() => {
checkUserSession();

(async () => {
const initialUrl = await Linking.getInitialURL();
console.log('Initial URL received:', initialUrl);
if (initialUrl) {
handleTokenFromUrl(initialUrl);
}
})();

const subscription = Linking.addEventListener('url', (event) => {
console.log('Deep link event received:', event.url);
handleTokenFromUrl(event.url);
});

return () => {
subscription.remove();
};
}, []);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix missing dependencies in useEffect

The current implementation has missing dependencies in the useEffect hook, which can lead to stale closures and unexpected behavior.

- useEffect(() => {
+ useEffect(() => {
    checkUserSession();

    (async () => {
      const initialUrl = await Linking.getInitialURL();
      console.log('Initial URL received:', initialUrl);
      if (initialUrl) {
        handleTokenFromUrl(initialUrl);
      }
    })();

    const subscription = Linking.addEventListener('url', (event) => {
      console.log('Deep link event received:', event.url);
      handleTokenFromUrl(event.url);
    });

    return () => {
      subscription.remove();
    };
- }, []);
+ }, [checkUserSession, handleTokenFromUrl]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
useEffect(() => {
checkUserSession();
(async () => {
const initialUrl = await Linking.getInitialURL();
console.log('Initial URL received:', initialUrl);
if (initialUrl) {
handleTokenFromUrl(initialUrl);
}
})();
const subscription = Linking.addEventListener('url', (event) => {
console.log('Deep link event received:', event.url);
handleTokenFromUrl(event.url);
});
return () => {
subscription.remove();
};
}, []);
useEffect(() => {
checkUserSession();
(async () => {
const initialUrl = await Linking.getInitialURL();
console.log('Initial URL received:', initialUrl);
if (initialUrl) {
handleTokenFromUrl(initialUrl);
}
})();
const subscription = Linking.addEventListener('url', (event) => {
console.log('Deep link event received:', event.url);
handleTokenFromUrl(event.url);
});
return () => {
subscription.remove();
};
}, [checkUserSession, handleTokenFromUrl]);
🧰 Tools
🪛 GitHub Check: build (18.x)

[failure] 73-73:
React Hook useEffect has missing dependencies: 'checkUserSession' and 'handleTokenFromUrl'. Either include them or remove the dependency array

🪛 GitHub Actions: Continous-Integeration

[error] 73-73: React Hook useEffect has missing dependencies: 'checkUserSession' and 'handleTokenFromUrl'. Either include them or remove the dependency array.

Comment on lines +32 to +38
const checkUserSession = async () => {
const token = await AsyncStorage.getItem('github_token');
if (token) {
console.log('User already logged in, redirecting to HomeScreen');
router.replace('/HomeScreen');
}
};
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider adding loading state during user session check

The function correctly checks for an existing token, but consider adding a loading state to improve user experience while the check is in progress.

const AuthScreen = () => {
  const router = useRouter();
+ const [isLoading, setIsLoading] = useState(false);

  // ... other code

  const checkUserSession = async () => {
+   setIsLoading(true);
    const token = await AsyncStorage.getItem('github_token');
    if (token) {
      console.log('User already logged in, redirecting to HomeScreen');
      router.replace('/HomeScreen');
    }
+   setIsLoading(false);
  };
  
  // ... and then use isLoading in your return JSX to show a loading indicator
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const checkUserSession = async () => {
const token = await AsyncStorage.getItem('github_token');
if (token) {
console.log('User already logged in, redirecting to HomeScreen');
router.replace('/HomeScreen');
}
};
const AuthScreen = () => {
const router = useRouter();
const [isLoading, setIsLoading] = useState(false);
// ... other code
const checkUserSession = async () => {
setIsLoading(true);
const token = await AsyncStorage.getItem('github_token');
if (token) {
console.log('User already logged in, redirecting to HomeScreen');
router.replace('/HomeScreen');
}
setIsLoading(false);
};
// ... and then use isLoading in your return JSX to show a loading indicator
return (
<View>
{isLoading ? (
<ActivityIndicator size="large" color="#0000ff" />
) : (
// ... other JSX content
)}
</View>
);
};

@konti-aditi konti-aditi closed this Apr 1, 2025
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.

1 participant