Skip to content

Conversation

@jaypanchal-13
Copy link
Contributor

@jaypanchal-13 jaypanchal-13 commented Dec 1, 2025

Product Description

Ticket -> https://dimagi.atlassian.net/browse/CCCT-1905
https://dimagi.atlassian.net/browse/CCCT-1941

Screen Shot's->
Left side img -> before and right side img -> After

image image image image image

video ->

Screen_recording_20251205_192123.mp4
Screen_recording_20251208_155736.mp4

Video for on loading menu item should work->

Screen_recording_20251209_145737.mp4

Technical Summary

Feature Flag

Safety Assurance

Safety story

All screens updated in this PR were manually verified. Toolbar interactions such as navigation icon clicks, overflow menu actions, contextual actions, and title updates were tested. No crashes, double action bars, or unexpected layout shifts were observed. Each modified screen has been tested for its full workflow.

Automated test coverage

QA Plan

Labels and Review

  • Do we need to enhance the manual QA test coverage ? If yes, the "QA Note" label is set correctly
  • Does the PR introduce any major changes worth communicating ? If yes, the "Release Note" label is set and a "Release Note" is specified in PR description.
  • Risk label is set correctly
  • The set of people pinged as reviewers is appropriate for the level of risk of the change

QA Note: Pay Special attention to the menus and app bar contents and check that the toolbar state remains consistent on doing menu actions and returning back to the page, on coming out of the app and getting into the app, on rotating the device.

@coderabbitai
Copy link

coderabbitai bot commented Dec 1, 2025

📝 Walkthrough

Walkthrough

This PR systematically adds Material Design AppBar and Toolbar components across multiple activities and layouts. The root layout for several activities transitions from ConstraintLayout/ScrollView to LinearLayout with AppBarLayout/CoordinatorLayout structures. Activity code is updated to initialize Toolbar instances, set them as support action bars, and enable up navigation. Title setting previously delegated to overridden setTitle methods is now handled through toolbar/navigation updates. Theme configuration changes from DarkActionBar to NoActionBar with WhiteNavIcon styling. Navigation drawer integration includes toolbar parameter updates to ActionBarDrawerToggle and new close button handling. Fragment title updates are moved from fragment initialization to activity-level navigation listener responses.

Sequence Diagram

sequenceDiagram
    actor User
    participant Activity
    participant Toolbar
    participant ActionBar
    participant DrawerToggle
    participant Fragment

    User->>Activity: App launches
    Activity->>Toolbar: findViewById(R.id.toolbar)
    Activity->>ActionBar: setSupportActionBar(toolbar)
    Activity->>ActionBar: setDisplayHomeAsUpEnabled(true)
    Activity->>DrawerToggle: new ActionBarDrawerToggle(..., toolbar, ...)
    DrawerToggle->>Toolbar: Update drawer icon color
    
    rect rgba(100, 200, 150, 0.2)
    Note over Activity,Fragment: Navigation Event
    end
    
    User->>Activity: Navigate to fragment
    Activity->>Fragment: Destination listener triggered
    Fragment->>ActionBar: Update title from navigation args
    ActionBar->>Toolbar: Display updated title

    User->>Activity: Tap drawer close button
    Activity->>DrawerToggle: Close drawer
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Areas requiring extra attention:

  • Layout restructuring files (activity_connect_id.xml, activity_connect_messaging.xml, home_screen.xml, update_activity.xml, first_start_screen_modern.xml): Each transitions to different root layout types (LinearLayout vs CoordinatorLayout); verify constraint/positioning logic is preserved and no UI breaks occur
  • Activity toolbar initialization (AppManagerActivity, CommCareSetupActivity, LoginActivity, UpdateActivity, ConnectActivity, ConnectMessagingActivity, PersonalIdActivity, PersonalIdWorkHistoryActivity, PushNotificationActivity): Confirm toolbar wiring is consistent and up navigation is correctly enabled across all classes
  • Title delegation changes (ConnectActivity, ConnectMessagingActivity, ConnectMessageFragment): Removal of setTitle overrides requires verification that titles are properly updated via navigation listeners and toolbar configuration
  • Drawer integration changes (BaseDrawerController.kt): ActionBarDrawerToggle constructor signature change and drawer close button handling need functional testing
  • Theme changes (themes.xml): Transition from DarkActionBar to NoActionBar bridge parent and introduction of WhiteNavIcon style should be validated against visual appearance

Possibly related PRs

Suggested labels

High Risk, QA Note

Suggested reviewers

  • Jignesh-dimagi
  • shubham1g5
  • OrangeAndGreen
  • conroy-ricketts

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.17% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ⚠️ Warning PR description is largely incomplete with missing critical technical details. The template has placeholders for Technical Summary, Feature Flag, test coverage, and QA Plan that remain unfilled. Complete the Technical Summary section with design rationale, specify feature flag if applicable, add automated test coverage details, provide QA Plan with test conditions, and remove placeholder comments to ensure the PR is fully documented for review.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main change: adding toolbars to activities to support the side navigation drawer overlay pattern.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch CCCT-1905

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
app/src/org/commcare/activities/connect/PersonalIdActivity.java (1)

81-84: Add null check to prevent potential NPE.

The setTitle method calls getSupportActionBar() without a null check, unlike updateBackButton() which properly guards against null. This inconsistency could lead to a crash.

 @Override
 public void setTitle(CharSequence title) {
     super.setTitle(title);
-    getSupportActionBar().setTitle(title);
+    ActionBar actionBar = getSupportActionBar();
+    if (actionBar != null) {
+        actionBar.setTitle(title);
+    }
 }
app/src/org/commcare/activities/connect/PersonalIdWorkHistoryActivity.kt (1)

51-66: Remove duplicate action bar configuration.

The action bar setup is performed twice with identical settings: once in setUpUi() (lines 62-66) and again in onPostCreate() (lines 53-57). Since setUpUi() is called from onCreate() which runs before onPostCreate(), the onPostCreate configuration is redundant.

Remove the duplicate configuration from onPostCreate:

 override fun onPostCreate(savedInstanceState: Bundle?) {
     super.onPostCreate(savedInstanceState)
-    supportActionBar!!.apply {
-        title = getString(R.string.personalid_work_history_title)
-        setDisplayShowHomeEnabled(true)
-        setDisplayHomeAsUpEnabled(true)
-    }
 }

Or, if you prefer to keep configuration in onPostCreate (which is a valid pattern for action bar setup), remove it from setUpUi instead.

🧹 Nitpick comments (11)
app/src/org/commcare/fragments/personalId/PersonalIdPhoneFragment.java (1)

103-103: Consider using the activity field consistently.

Line 103 calls requireActivity().setTitle(...) while the rest of the file uses the activity field (initialized at line 101). For consistency, either use activity.setTitle(R.string.connect_registration_title) here or refactor the entire file to use requireActivity() directly instead of caching it in the activity field.

app/src/org/commcare/activities/PushNotificationActivity.kt (1)

66-81: Avoid duplicating action bar configuration between onPostCreate and initViews

supportActionBar is configured twice: once in onPostCreate and again right after setSupportActionBar(binding.toolbarNotification) in initViews. This is redundant and risks future divergence (e.g., one place updated, the other forgotten).

Since you now set the toolbar as the support action bar in initViews, you can centralize all configuration there and remove the onPostCreate override.

Example refactor:

-    override fun onPostCreate(savedInstanceState: Bundle?) {
-        super.onPostCreate(savedInstanceState)
-        supportActionBar!!.apply {
-            title = getString(R.string.personalid_notification)
-            setDisplayShowHomeEnabled(true)
-            setDisplayHomeAsUpEnabled(true)
-        }
-    }
-
-    private fun initViews() {
-        setSupportActionBar(binding.toolbarNotification)
-        supportActionBar!!.apply {
-            title = getString(R.string.personalid_notification)
-            setDisplayShowHomeEnabled(true)
-            setDisplayHomeAsUpEnabled(true)
-        }
+    private fun initViews() {
+        setSupportActionBar(binding.toolbarNotification)
+        supportActionBar!!.apply {
+            title = getString(R.string.personalid_notification)
+            setDisplayShowHomeEnabled(true)
+            setDisplayHomeAsUpEnabled(true)
+        }

This keeps all toolbar/title logic in a single, obvious place.

app/src/org/commcare/activities/CommCareSetupActivity.java (1)

188-190: Consider adding null safety for toolbar initialization.

If the layout R.layout.first_start_screen_modern does not contain a view with R.id.toolbar, findViewById returns null, and passing null to setSupportActionBar followed by getSupportActionBar() calls will cause issues.

 Toolbar toolbar = findViewById(R.id.toolbar);
-setSupportActionBar(toolbar);
-getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+if (toolbar != null) {
+    setSupportActionBar(toolbar);
+    ActionBar actionBar = getSupportActionBar();
+    if (actionBar != null) {
+        actionBar.setDisplayHomeAsUpEnabled(true);
+    }
+}
app/src/org/commcare/activities/AppManagerActivity.java (1)

54-56: Consider adding a null check for defensive coding.

While the toolbar should be present given the layout changes, adding a null check would make the code more resilient to future layout modifications.

         Toolbar toolbar = findViewById(R.id.toolbar);
-        setSupportActionBar(toolbar);
-        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+        if (toolbar != null) {
+            setSupportActionBar(toolbar);
+            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+        }
app/res/layout/screen_connect.xml (1)

14-15: Consider consistent toolbar id naming across layouts.

This file uses toolbar_connect_activity while other layouts in this PR use just toolbar. If intentional (e.g., to avoid conflicts), this is fine; otherwise, consider standardizing for consistency.

app/res/values/themes.xml (1)

35-36: Validate global icon tinting and toolbar nav style impact

Setting toolbarNavigationButtonStyle to WhiteNavIcon and colorControlNormal to @android:color/white will make many controls and icons render white by default, not just toolbar navigation buttons. Verify across key flows (forms, lists, dialogs) that this global tint does not reduce contrast or make non-toolbar icons invisible on light backgrounds; if it does, consider narrowing the white tint to just toolbar/navigation icons.

Also applies to: 112-115

app/res/layout/update_activity.xml (1)

2-153: Minor layout polish for scrolling and button row spacing

The CoordinatorLayout/AppBarLayout/Toolbar setup looks correct, and the IDs match the controller expectations. Consider (a) adding android:fillViewport="true" to the ScrollView so short-content screens still stretch to full height, and (b) replacing the hard-coded 100dp paddings in @id/update_check_cancel_buttons with a dimen resource or a centering approach (e.g., gravity="center_horizontal" plus smaller margins) to avoid overly cramped buttons on small screens.

app/res/layout/home_screen.xml (1)

28-110: Tighten NestedScrollView sizing for more predictable scrolling

The NestedScrollView inside the vertical LinearLayout currently uses android:layout_height="wrap_content", which can lead to slightly odd behavior when content is short or when the parent height changes. Consider switching to a fill pattern, e.g.:

-                <androidx.core.widget.NestedScrollView
+                <androidx.core.widget.NestedScrollView
                     android:id="@+id/nsv_home_screen"
                     android:layout_width="match_parent"
-                    android:layout_height="wrap_content">
+                    android:layout_height="match_parent"
+                    android:fillViewport="true">

This keeps the content pinned correctly under the toolbar and avoids partial-height scroll containers.

app/src/org/commcare/activities/LoginActivity.java (1)

26-27: Make toolbar setup null-safe and confirm layout is inflated before use

The new Toolbar wiring is straightforward, but it assumes (a) that a view with @id/toolbar is present in all layouts used by this activity, and (b) that getSupportActionBar() is non-null:

Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

To harden this, add null checks and, given the BaseDrawerActivity hierarchy, double-check that the content view is set (via the base class or UI controller) before calling findViewById:

-        Toolbar toolbar = findViewById(R.id.toolbar);
-        setSupportActionBar(toolbar);
-        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+        Toolbar toolbar = findViewById(R.id.toolbar);
+        if (toolbar != null) {
+            setSupportActionBar(toolbar);
+            if (getSupportActionBar() != null) {
+                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+            }
+        }

Please also verify that this does not conflict with any toolbar/drawer wiring already performed in BaseDrawerActivity.

Also applies to: 133-139

app/src/org/commcare/navdrawer/DrawerViewRefs.kt (1)

9-10: Avoid hard non-null assumptions for toolbar/closeButton in shared drawer refs

DrawerViewRefs now assumes every root view using the drawer has both R.id.toolbar and R.id.nav_drawer_close:

val toolbar: Toolbar = rootView.findViewById(R.id.toolbar)
val closeButton: ImageView = rootView.findViewById(R.id.nav_drawer_close)

If any screen with a drawer omits either view, you'll get an immediate NPE during construction. Either (a) ensure all drawer layouts define these IDs, or (b) make these properties nullable (and handled accordingly in BaseDrawerActivity/controllers), e.g. val toolbar: Toolbar? = ..., to keep the shared helper resilient.

Also applies to: 29-30

app/src/org/commcare/activities/connect/ConnectActivity.java (1)

167-171: Remove commented code.

Dead code should be deleted rather than commented out. Git history preserves the old implementation if needed.

Apply this diff:

-    /*@Override
-    public void setTitle(CharSequence title) {
-        super.setTitle(title);
-        getSupportActionBar().setTitle(title);
-    }*/
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a81e3a5 and eb30114.

📒 Files selected for processing (26)
  • app/res/layout/activity_connect_id.xml (1 hunks)
  • app/res/layout/activity_connect_messaging.xml (1 hunks)
  • app/res/layout/activity_personal_id_work_history.xml (2 hunks)
  • app/res/layout/activity_push_notification.xml (3 hunks)
  • app/res/layout/app_manager.xml (1 hunks)
  • app/res/layout/first_start_screen_modern.xml (1 hunks)
  • app/res/layout/home_screen.xml (1 hunks)
  • app/res/layout/nav_drawer_header.xml (1 hunks)
  • app/res/layout/screen_connect.xml (1 hunks)
  • app/res/layout/screen_login.xml (2 hunks)
  • app/res/layout/update_activity.xml (1 hunks)
  • app/res/navigation/nav_graph_connect_messaging.xml (1 hunks)
  • app/res/values/themes.xml (3 hunks)
  • app/src/org/commcare/activities/AppManagerActivity.java (2 hunks)
  • app/src/org/commcare/activities/CommCareSetupActivity.java (2 hunks)
  • app/src/org/commcare/activities/LoginActivity.java (2 hunks)
  • app/src/org/commcare/activities/PushNotificationActivity.kt (2 hunks)
  • app/src/org/commcare/activities/UpdateActivity.java (2 hunks)
  • app/src/org/commcare/activities/connect/ConnectActivity.java (3 hunks)
  • app/src/org/commcare/activities/connect/ConnectMessagingActivity.java (3 hunks)
  • app/src/org/commcare/activities/connect/PersonalIdActivity.java (2 hunks)
  • app/src/org/commcare/activities/connect/PersonalIdWorkHistoryActivity.kt (1 hunks)
  • app/src/org/commcare/fragments/connectMessaging/ConnectMessageFragment.java (0 hunks)
  • app/src/org/commcare/fragments/personalId/PersonalIdPhoneFragment.java (2 hunks)
  • app/src/org/commcare/navdrawer/BaseDrawerController.kt (4 hunks)
  • app/src/org/commcare/navdrawer/DrawerViewRefs.kt (2 hunks)
💤 Files with no reviewable changes (1)
  • app/src/org/commcare/fragments/connectMessaging/ConnectMessageFragment.java
🧰 Additional context used
🧠 Learnings (13)
📓 Common learnings
Learnt from: shubham1g5
Repo: dimagi/commcare-android PR: 0
File: :0-0
Timestamp: 2025-05-08T11:08:18.530Z
Learning: PR #3048 "Phase 4 Connect PR" introduces a substantial feature called "Connect" to the CommCare Android app, which includes messaging, job management, delivery tracking, payment processing, authentication flows, and learning modules. It follows a modern architecture using Navigation Components with three navigation graphs, segregated business logic in Manager classes, and proper database persistence.
📚 Learning: 2025-05-09T10:57:41.073Z
Learnt from: Jignesh-dimagi
Repo: dimagi/commcare-android PR: 3093
File: app/res/navigation/nav_graph_connect_messaging.xml:41-45
Timestamp: 2025-05-09T10:57:41.073Z
Learning: In the CommCare Android codebase, the navigation graph for Connect messaging (`nav_graph_connect_messaging.xml`) intentionally uses `channel_id` as the argument name in the connectMessageFragment, despite using `channelId` in other parts of the same navigation graph. This naming difference is by design in the refactored code.

Applied to files:

  • app/res/navigation/nav_graph_connect_messaging.xml
  • app/res/layout/activity_connect_messaging.xml
  • app/src/org/commcare/activities/connect/ConnectMessagingActivity.java
  • app/res/layout/activity_connect_id.xml
  • app/res/layout/screen_connect.xml
  • app/src/org/commcare/fragments/personalId/PersonalIdPhoneFragment.java
📚 Learning: 2025-05-08T11:08:18.530Z
Learnt from: shubham1g5
Repo: dimagi/commcare-android PR: 0
File: :0-0
Timestamp: 2025-05-08T11:08:18.530Z
Learning: PR #3048 "Phase 4 Connect PR" introduces a substantial feature called "Connect" to the CommCare Android app, which includes messaging, job management, delivery tracking, payment processing, authentication flows, and learning modules. It follows a modern architecture using Navigation Components with three navigation graphs, segregated business logic in Manager classes, and proper database persistence.

Applied to files:

  • app/res/navigation/nav_graph_connect_messaging.xml
  • app/res/layout/home_screen.xml
  • app/res/layout/activity_connect_messaging.xml
  • app/src/org/commcare/activities/connect/ConnectMessagingActivity.java
  • app/res/layout/activity_connect_id.xml
  • app/res/layout/screen_connect.xml
  • app/src/org/commcare/activities/connect/ConnectActivity.java
📚 Learning: 2025-02-19T15:15:01.935Z
Learnt from: pm-dimagi
Repo: dimagi/commcare-android PR: 2956
File: app/src/org/commcare/fragments/connectMessaging/ConnectMessageChannelListFragment.java:58-60
Timestamp: 2025-02-19T15:15:01.935Z
Learning: Error handling for message retrieval in ConnectMessageChannelListFragment's retrieveMessages callback is not required as per user preference.

Applied to files:

  • app/res/navigation/nav_graph_connect_messaging.xml
  • app/src/org/commcare/activities/connect/ConnectMessagingActivity.java
📚 Learning: 2025-05-22T14:28:35.959Z
Learnt from: OrangeAndGreen
Repo: dimagi/commcare-android PR: 3121
File: app/src/org/commcare/activities/CommCareSetupActivity.java:360-364
Timestamp: 2025-05-22T14:28:35.959Z
Learning: In CommCareSetupActivity.java, the call to installFragment.showConnectErrorMessage() after fragment transactions is intentionally unguarded with null checks. This follows the app's design pattern where critical error paths prefer immediate crashes over silent failures, making potential issues immediately visible during development rather than hiding them with defensive programming.

Applied to files:

  • app/res/navigation/nav_graph_connect_messaging.xml
  • app/src/org/commcare/activities/PushNotificationActivity.kt
📚 Learning: 2025-06-04T19:17:21.213Z
Learnt from: OrangeAndGreen
Repo: dimagi/commcare-android PR: 3108
File: app/src/org/commcare/fragments/connect/ConnectUnlockFragment.java:62-64
Timestamp: 2025-06-04T19:17:21.213Z
Learning: In ConnectUnlockFragment.java, the user prefers to let getArguments() potentially throw NullPointerException rather than adding null checks, as the arguments are required for proper navigation flow and their absence indicates a programming error that should fail fast.

Applied to files:

  • app/res/navigation/nav_graph_connect_messaging.xml
  • app/src/org/commcare/activities/connect/ConnectMessagingActivity.java
  • app/src/org/commcare/activities/connect/PersonalIdActivity.java
  • app/src/org/commcare/activities/connect/ConnectActivity.java
📚 Learning: 2025-07-29T14:09:49.805Z
Learnt from: OrangeAndGreen
Repo: dimagi/commcare-android PR: 3248
File: app/src/org/commcare/fragments/connectMessaging/ConnectMessageFragment.java:0-0
Timestamp: 2025-07-29T14:09:49.805Z
Learning: In the CommCare Android Connect messaging system, message retry logic is implemented at the MessageManager level via MessageManager.sendUnsentMessages(). This method is called automatically when the channel list loads (ConnectMessageChannelListFragment), and it attempts to resend any outgoing messages that are not yet confirmed. Individual message fragments do not need to implement their own retry logic.

Applied to files:

  • app/res/navigation/nav_graph_connect_messaging.xml
📚 Learning: 2025-07-29T14:14:07.954Z
Learnt from: OrangeAndGreen
Repo: dimagi/commcare-android PR: 3248
File: app/src/org/commcare/adapters/ConnectMessageAdapter.java:0-0
Timestamp: 2025-07-29T14:14:07.954Z
Learning: In the CommCare Android Connect messaging system (ConnectMessageAdapter.java), the team prefers to let getMessage() potentially return null and crash rather than adding defensive null checks. This follows the fail-fast philosophy used throughout the Connect feature to catch programming errors immediately during development.

Applied to files:

  • app/res/navigation/nav_graph_connect_messaging.xml
  • app/res/layout/activity_connect_messaging.xml
📚 Learning: 2025-05-07T06:49:29.295Z
Learnt from: Jignesh-dimagi
Repo: dimagi/commcare-android PR: 3070
File: app/res/values/attrs.xml:98-113
Timestamp: 2025-05-07T06:49:29.295Z
Learning: In Android resource files, attributes like `editTextHintColor` and `editTextHintSize` can be defined once globally with format declarations and then reused in multiple styleables without repeating the format. This is the proper pattern for attribute reuse in Android's resource system.

Applied to files:

  • app/res/values/themes.xml
📚 Learning: 2025-05-07T06:48:32.621Z
Learnt from: Jignesh-dimagi
Repo: dimagi/commcare-android PR: 3070
File: app/res/values/themes.xml:80-80
Timestamp: 2025-05-07T06:48:32.621Z
Learning: The CommCare Android app doesn't require backward compatibility for support library features like the vector drawable compatibility provided by app:srcCompat. It uses android:src directly for drawable references in themes.

Applied to files:

  • app/res/values/themes.xml
📚 Learning: 2025-05-09T13:45:18.661Z
Learnt from: Jignesh-dimagi
Repo: dimagi/commcare-android PR: 3093
File: app/res/layout/activity_connect_messaging.xml:0-0
Timestamp: 2025-05-09T13:45:18.661Z
Learning: In Android ConstraintLayout, use `layout_constraintStart_toStartOf` and `layout_constraintEnd_toEndOf` instead of the deprecated `layout_constraintLeft_toLeftOf` and `layout_constraintRight_toRightOf` to ensure proper RTL (Right-to-Left) layout support for languages like Arabic, Hebrew, and Persian.

Applied to files:

  • app/res/layout/activity_push_notification.xml
📚 Learning: 2025-05-09T13:45:18.661Z
Learnt from: Jignesh-dimagi
Repo: dimagi/commcare-android PR: 3093
File: app/res/layout/activity_connect_messaging.xml:0-0
Timestamp: 2025-05-09T13:45:18.661Z
Learning: In Android layouts, use `layout_constraintStart_toStartOf` and `layout_constraintEnd_toEndOf` instead of the deprecated `layout_constraintLeft_toLeftOf` and `layout_constraintRight_toRightOf` to ensure proper RTL (Right-to-Left) layout support.

Applied to files:

  • app/res/layout/activity_push_notification.xml
📚 Learning: 2025-05-09T07:05:19.320Z
Learnt from: Jignesh-dimagi
Repo: dimagi/commcare-android PR: 3093
File: app/res/layout/dialog_payment_confirmation.xml:57-65
Timestamp: 2025-05-09T07:05:19.320Z
Learning: In a ConstraintLayout, a view with width set to wrap_content only needs a single horizontal constraint (either start or end) for proper positioning, as opposed to views with match_constraint (0dp) width which require both horizontal constraints to determine their size.

Applied to files:

  • app/res/layout/activity_push_notification.xml
🧬 Code graph analysis (1)
app/src/org/commcare/navdrawer/BaseDrawerController.kt (1)
app/src/org/commcare/navdrawer/BaseDrawerActivity.kt (1)
  • closeDrawer (136-145)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Lint Code Base
🔇 Additional comments (18)
app/src/org/commcare/activities/PushNotificationActivity.kt (1)

4-4: Import addition is fine

Adding android.util.Log is consistent with typical Android usage; no issues here.

app/src/org/commcare/activities/connect/PersonalIdActivity.java (1)

21-22: LGTM - Toolbar setup follows the established pattern.

The toolbar initialization is consistent with other activities in this PR.

app/res/layout/activity_personal_id_work_history.xml (2)

9-24: LGTM - AppBarLayout with Toolbar correctly integrated.

The toolbar structure follows the established pattern in this PR, and the toolbar ID correctly matches the binding reference in PersonalIdWorkHistoryActivity.kt (binding.toolbar).


26-34: LGTM - TabLayout positioning updated correctly.

The TabLayout is now properly constrained below the new app bar, maintaining the correct visual hierarchy.

app/res/layout/activity_push_notification.xml (1)

10-25: LGTM - AppBarLayout and Toolbar structure is correct.

The layout follows the Material Design pattern with proper constraints. The toolbar ID toolbar_notification is activity-specific and correctly referenced in PushNotificationActivity via data binding (binding.toolbarNotification).

app/res/layout/app_manager.xml (1)

9-22: LGTM!

The Toolbar is correctly positioned at the top of the RelativeLayout, and the FrameLayout is properly constrained below it using layout_below. The structure maintains correct content flow.

app/res/layout/screen_connect.xml (1)

7-20: LGTM - ConstraintLayout approach is correct.

Using 0dp dimensions with constraints properly fills the remaining space in ConstraintLayout. The popupTheme addition ensures consistent overflow menu styling.

app/res/values/themes.xml (1)

4-4: Confirm all activities are compatible with NoActionBar base theme

Changing CommonTheme to Theme.MaterialComponents.Light.NoActionBar.Bridge removes the framework action bar; any activity still assuming a built-in action bar or calling getSupportActionBar() without setting a Toolbar will break. Please confirm all such activities have either been updated to provide a Toolbar or guarded appropriately.

app/res/layout/first_start_screen_modern.xml (1)

2-49: Toolbar + drawer integration looks consistent

The new DrawerLayout/CoordinatorLayout/AppBarLayout/Toolbar structure with @id/nav_drawer_frame aligns with the updated home/login screens and should work well with the shared drawer controller. No issues from this diff.

app/res/layout/screen_login.xml (1)

6-6: Toolbar integration on login screen looks good; confirm drawer wiring

The added AppBarLayout/Toolbar at the top of the login content is consistent with the other updated drawer-based layouts and provides a proper app bar for LoginActivity. Please just confirm that this @id/toolbar is the one DrawerViewRefs/BaseDrawerActivity expect to use for drawer toggling and that no duplicate toolbars exist in alternative login layouts (e.g., flavors/orientations).

Also applies to: 21-35

app/src/org/commcare/activities/UpdateActivity.java (1)

109-113: Guard Toolbar/action bar setup against nulls

findViewById(R.id.toolbar) and getSupportActionBar() are both assumed non-null; any alternate layout for this activity without a @id/toolbar (or a failure to set the support action bar) will crash here. Wrap this block in null checks so the activity remains safe even if the toolbar is absent in some configurations:

-        Toolbar toolbar = findViewById(R.id.toolbar);
-        setSupportActionBar(toolbar);
-        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+        Toolbar toolbar = findViewById(R.id.toolbar);
+        if (toolbar != null) {
+            setSupportActionBar(toolbar);
+            if (getSupportActionBar() != null) {
+                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+            }
+        }
⛔ Skipped due to learnings
Learnt from: OrangeAndGreen
Repo: dimagi/commcare-android PR: 3121
File: app/src/org/commcare/activities/CommCareSetupActivity.java:360-364
Timestamp: 2025-05-22T14:28:35.959Z
Learning: In CommCareSetupActivity.java, the call to installFragment.showConnectErrorMessage() after fragment transactions is intentionally unguarded with null checks. This follows the app's design pattern where critical error paths prefer immediate crashes over silent failures, making potential issues immediately visible during development rather than hiding them with defensive programming.
app/res/navigation/nav_graph_connect_messaging.xml (1)

39-39: LGTM! Dynamic title handling moved to activity level.

The empty label aligns with the dynamic title setting implemented in ConnectMessagingActivity's OnDestinationChangedListener (lines 61-73 of ConnectMessagingActivity.java), where the action bar title is now set at runtime based on the channel data.

app/src/org/commcare/activities/connect/ConnectActivity.java (1)

70-70: LGTM! Toolbar integration follows Android best practices.

The toolbar is properly initialized and set as the support action bar with the Up button enabled.

Also applies to: 75-77

app/src/org/commcare/navdrawer/BaseDrawerController.kt (2)

58-60: LGTM! Toolbar-based action bar setup with consistent white theming.

The drawer controller properly integrates the toolbar as the action bar and applies white color to both the title text and navigation icon, aligning with the WhiteNavIcon theme introduced in this PR.

Also applies to: 65-65, 91-91


119-119: LGTM! Close button properly wired to drawer close action.

The click listener correctly invokes the closeDrawer() method.

app/src/org/commcare/activities/connect/ConnectMessagingActivity.java (2)

30-30: LGTM! Toolbar properly initialized.

The toolbar is correctly set as the support action bar following the standard Android pattern.

Also applies to: 36-37


51-74: No action required—the null handling is already correct.

The navigation argument channel_id is declared as app:nullable="false" in the navigation graph and always provided through showConnectMessageFragment(). The null checks on lines 62-64 are defensive and will always pass. If the database lookup fails on line 66, not updating the title is correct behavior and preserves the previous fragment's title appropriately.

app/res/layout/nav_drawer_header.xml (1)

25-67: LGTM! Profile section properly restructured.

The CardView-based profile layout with horizontal arrangement of avatar and user info follows Material Design patterns and maintains all necessary view IDs for code compatibility.

Comment on lines 10 to 17
<ImageView
android:id="@+id/nav_drawer_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/image_user_profile"
android:layout_width="64dp"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:scaleType="centerCrop"
app:shapeAppearanceOverlay="@style/CircularImageView"
android:src="@drawable/nav_drawer_person_avatar"/>
android:src="@drawable/ic_connect_close"
app:tint="@color/white"
android:layout_gravity="start"
android:layout_marginBottom="16dp"/>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add contentDescription for accessibility.

The close button ImageView is missing a contentDescription attribute, which is needed for screen readers.

Apply this diff:

 <ImageView
     android:id="@+id/nav_drawer_close"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:src="@drawable/ic_connect_close"
+    android:contentDescription="@string/close_navigation_drawer"
     app:tint="@color/white"
     android:layout_gravity="start"
     android:layout_marginBottom="16dp"/>

Note: You'll need to add the string resource close_navigation_drawer to your strings.xml file.

📝 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
<ImageView
android:id="@+id/nav_drawer_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/image_user_profile"
android:layout_width="64dp"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:scaleType="centerCrop"
app:shapeAppearanceOverlay="@style/CircularImageView"
android:src="@drawable/nav_drawer_person_avatar"/>
android:src="@drawable/ic_connect_close"
app:tint="@color/white"
android:layout_gravity="start"
android:layout_marginBottom="16dp"/>
<ImageView
android:id="@+id/nav_drawer_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_connect_close"
android:contentDescription="@string/close_navigation_drawer"
app:tint="@color/white"
android:layout_gravity="start"
android:layout_marginBottom="16dp"/>
🤖 Prompt for AI Agents
In app/res/layout/nav_drawer_header.xml around lines 10 to 17, the ImageView
with id nav_drawer_close lacks a contentDescription which breaks accessibility;
add the attribute android:contentDescription="@string/close_navigation_drawer"
to the ImageView and then add a string resource named close_navigation_drawer to
your res/values/strings.xml (e.g., "Close navigation drawer") so screen readers
can describe the control.

Copy link
Contributor

@conroy-ricketts conroy-ricketts left a comment

Choose a reason for hiding this comment

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

Love this change! I just had a few minor comments

Also, I think it'd be worth it to address what Code Rabbit said too, including the nitpick comments (besides maybe the comments about null checks)

Comment on lines 17 to 18
android:background="?attr/colorPrimary"
app:titleTextColor="@android:color/white"/>
Copy link
Contributor

Choose a reason for hiding this comment

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

This does not need to change, but out of curiosity, why does the team directly use color resources in some places but use theme attributes in others?

Using theme attributes as much as possible makes it a lot easier to add/edit new app themes in the future (e.g. a dark mode).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

+1 for using theme attributes. I am not sure but I think there is not evidence of giving dark mode support as of now that can be reason, we are using color resources in some place

Copy link
Contributor

@shubham1g5 shubham1g5 left a comment

Choose a reason for hiding this comment

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

Can we add before and after screenshots for all screen we are replacing the action bar with a tool bar on, the PR should also be labelled as QA note and specify testing notes. It should also specify a safety story confirming you have tested each of the screen and action bar interactions for all screens you are making this change on.

Also please try to separate out these changes in different commits or PRs if applicable, it's not alright to push all changes in a bulk single commit.

@jaypanchal-13
Copy link
Contributor Author

Can we add before and after screenshots for all screen we are replacing the action bar with a tool bar on, the PR should also be labelled as QA note and specify testing notes. It should also specify a safety story confirming you have tested each of the screen and action bar interactions for all screens you are making this change on.

Also please try to separate out these changes in different commits or PRs if applicable, it's not alright to push all changes in a bulk single commit.

@shubham1g5 As mentioned in this ticket. Creating different PR's for all this screen and attaching before and after screen shot on that PR's

conroy-ricketts
conroy-ricketts previously approved these changes Dec 3, 2025
Copy link
Contributor

@conroy-ricketts conroy-ricketts left a comment

Choose a reason for hiding this comment

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

Updating my review to non-blocking, but I think Shubham's suggestion should be addressed before merging this code in

@jaypanchal-13
Copy link
Contributor Author

@damagatchi retest this please

@Jignesh-dimagi
Copy link
Contributor

@jaypanchal-13
Every xml file and activity needs to be changed with your approach. Can create separate xml for AppBarLayout and name it appbar_layout.xml and it can be included in each screen xml file.
This will ensures consistency in AppBarLayout appearance and behavior across various screens and it's reusability.

Also, for activity if we can try to put this code in parent activity and not in individual activity screen. We need to check if toolbar present or not.

        toolbar = findViewById(R.id.toolbar_connect_activity);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

This way we don't have to change code in individual activity every time but just include appbar_layout.xml in it's layout.

@jaypanchal-13
Copy link
Contributor Author

@jaypanchal-13 Every xml file and activity needs to be changed with your approach. Can create separate xml for AppBarLayout and name it appbar_layout.xml and it can be included in each screen xml file. This will ensures consistency in AppBarLayout appearance and behavior across various screens and it's reusability.

Also, for activity if we can try to put this code in parent activity and not in individual activity screen. We need to check if toolbar present or not.

        toolbar = findViewById(R.id.toolbar_connect_activity);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

This way we don't have to change code in individual activity every time but just include appbar_layout.xml in it's layout.

@Jignesh-dimagi Thanks for cleanup suggestion but then also we will need to set title in each child activity

@Jignesh-dimagi
Copy link
Contributor

@Jignesh-dimagi Thanks for cleanup suggestion but then also we will need to set title in each child activity

I think that's should be Ok but defining AppBarLayout in each layout and having same duplicate code in each screen can be avoided.

@Jignesh-dimagi
Copy link
Contributor

@jaypanchal-13 Also, in the side left navigation drawer, having cross X button on left with Commcare below looks somewhat odd, is that something designer / product has approved?

@jaypanchal-13
Copy link
Contributor Author

@jaypanchal-13 Also, in the side left navigation drawer, having cross X button on left with Commcare below looks somewhat odd, is that something designer / product has approved?

Yes, it looks little odd and you can find here. I have used already existed icon for this.

@Jignesh-dimagi
Copy link
Contributor

Yes, it looks little odd and you can find here. I have used already existed icon for this.

Ok. I think we need to reduce the vertical gap between the X cross and CommCare logo which is in Figma design.

@jaypanchal-13
Copy link
Contributor Author

@damagatchi retest this please

@jaypanchal-13
Copy link
Contributor Author

@jaypanchal-13 We also need to test that this change doesn't break edge to edge support , approving this assuming that works as expected.

Yes its working attaching screen shot bellow

Android 16

Screenshot_20251212_123145

Android 12

Screenshot_20251212_123414

Jignesh-dimagi
Jignesh-dimagi previously approved these changes Dec 12, 2025
@shubham1g5
Copy link
Contributor

@damagatchi retest this please

@jaypanchal-13
Copy link
Contributor Author

@damagatchi retest this please

1 similar comment
@jaypanchal-13
Copy link
Contributor Author

@damagatchi retest this please

@jaypanchal-13
Copy link
Contributor Author

@damagatchi retest this please

@jaypanchal-13
Copy link
Contributor Author

@damagatchi retest this please

shubham1g5
shubham1g5 previously approved these changes Dec 19, 2025
Copy link
Contributor

@shubham1g5 shubham1g5 left a comment

Choose a reason for hiding this comment

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

There is comment pending but making my review non-blocking as I am offline next week.

@Jignesh-dimagi
Copy link
Contributor

@jaypanchal-13 This looks good now

@jaypanchal-13 jaypanchal-13 merged commit 8e85035 into master Dec 22, 2025
7 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants