Conversation
- Persist confirmed study_user_id after successful study enrollment - Store the study ID alongside the existing pseudoId using a dedicated preference key - Append study_user_id only to app_launch Firebase event parameters when available - Leave unenrolled app_launch events unchanged by omitting study_user_id - Add unit coverage for app_launch events with and without a persisted study_user_id - Restore the existing language_selected analytics test invocation so the test class passes
📝 WalkthroughWalkthroughThis PR enhances analytics tracking by storing a study user ID during ID confirmation and enriches app_launch events with that ID, while updating the confirmation UX with a new success dialog that auto-dismisses and displays celebratory feedback before showing the language selection. ChangesStudy User ID Analytics and Enrollment Success
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/src/main/java/org/curiouslearning/container/MainActivity.java`:
- Around line 470-506: The showSuccessDialog method currently calls
successDialog.show() and schedules dismissal without checking Activity state;
before creating or showing the Dialog (inside runOnUiThread), guard with
Activity lifecycle checks (isFinishing() and, on API >=17, isDestroyed()) to
avoid showing or scheduling UI when the Activity is finishing/destroyed; apply
the same guard before calling successDialog.show(), before postDelayed
scheduling, and in the OnDismissListener to ensure onDismissAction.run() is only
invoked when the Activity is valid.
In `@app/src/main/res/layout/dialog_enrollment_success.xml`:
- Around line 17-25: The TextView in dialog_enrollment_success.xml is using a
hardcoded emoji ("🎉") in android:text which is not accessible; replace the
hardcoded text with a string resource (e.g., add <string
name="enrollment_success_message">Enrollment successful</string> to
res/values/strings.xml) and set the TextView's android:text to that resource
(android:text="`@string/enrollment_success_message`"); ensure the TextView also
provides an accessible label for TalkBack (e.g., via android:contentDescription
referencing the same string) so screen readers receive meaningful feedback.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 6d1ea314-6d75-4eca-a326-1c63792589a5
📒 Files selected for processing (5)
app/build.gradleapp/src/main/java/org/curiouslearning/container/MainActivity.javaapp/src/main/java/org/curiouslearning/container/firebase/AnalyticsUtils.javaapp/src/main/res/layout/dialog_enrollment_success.xmlapp/src/test/java/org/curiouslearning/container/AnalyticsUtilsCustomEventsTest.java
| private void showSuccessDialog(Runnable onDismissAction) { | ||
| runOnUiThread(() -> { | ||
| try { | ||
| final Dialog successDialog = new Dialog(this); | ||
| successDialog.setContentView(R.layout.dialog_enrollment_success); | ||
| successDialog.setCanceledOnTouchOutside(true); | ||
| successDialog.setOnDismissListener(dialog -> { | ||
| if (onDismissAction != null) { | ||
| onDismissAction.run(); | ||
| } | ||
| }); | ||
| if (successDialog.getWindow() != null) { | ||
| successDialog.getWindow().setBackgroundDrawable(new android.graphics.drawable.ColorDrawable(android.graphics.Color.TRANSPARENT)); | ||
| } | ||
|
|
||
| View container = successDialog.findViewById(R.id.success_container); | ||
| if (container != null) { | ||
| container.setOnClickListener(v -> { | ||
| if (successDialog.isShowing()) { | ||
| successDialog.dismiss(); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| successDialog.show(); | ||
|
|
||
| new Handler(Looper.getMainLooper()).postDelayed(() -> { | ||
| if (successDialog.isShowing()) { | ||
| successDialog.dismiss(); | ||
| } | ||
| }, 2000); | ||
|
|
||
| } catch (Exception e) { | ||
| Log.e(TAG, "showSuccessDialog: Failed to show success dialog", e); | ||
| } | ||
| }); | ||
| } |
There was a problem hiding this comment.
Add an Activity lifecycle guard before showing the success dialog.
At Line 494, successDialog.show() can still run while the Activity is finishing/destroyed. That path is caught, but it can silently skip the intended post-confirmation UX flow.
Proposed fix
private void showSuccessDialog(Runnable onDismissAction) {
runOnUiThread(() -> {
try {
+ if (isFinishing() || isDestroyed()) {
+ Log.w(TAG, "showSuccessDialog: Activity is finishing or destroyed, not showing dialog.");
+ return;
+ }
final Dialog successDialog = new Dialog(this);
successDialog.setContentView(R.layout.dialog_enrollment_success);
successDialog.setCanceledOnTouchOutside(true);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/src/main/java/org/curiouslearning/container/MainActivity.java` around
lines 470 - 506, The showSuccessDialog method currently calls
successDialog.show() and schedules dismissal without checking Activity state;
before creating or showing the Dialog (inside runOnUiThread), guard with
Activity lifecycle checks (isFinishing() and, on API >=17, isDestroyed()) to
avoid showing or scheduling UI when the Activity is finishing/destroyed; apply
the same guard before calling successDialog.show(), before postDelayed
scheduling, and in the OnDismissListener to ensure onDismissAction.run() is only
invoked when the Activity is valid.
| <TextView | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:text="🎉" | ||
| android:textSize="80sp" | ||
| app:layout_constraintTop_toTopOf="parent" | ||
| app:layout_constraintBottom_toBottomOf="parent" | ||
| app:layout_constraintStart_toStartOf="parent" | ||
| app:layout_constraintEnd_toEndOf="parent" /> |
There was a problem hiding this comment.
Avoid emoji-only hardcoded text for success messaging.
At Line 20, the dialog uses hardcoded emoji text only. Please move text to a string resource and provide accessible success text so TalkBack users get meaningful feedback.
Proposed fix
- <TextView
+ <TextView
+ android:id="@+id/success_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="🎉"
+ android:text="`@string/enrollment_success_message`"
+ android:contentDescription="`@string/enrollment_success_message`"
android:textSize="80sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" /><!-- res/values/strings.xml -->
<string name="enrollment_success_message">Enrollment successful</string>📝 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.
| <TextView | |
| android:layout_width="wrap_content" | |
| android:layout_height="wrap_content" | |
| android:text="🎉" | |
| android:textSize="80sp" | |
| app:layout_constraintTop_toTopOf="parent" | |
| app:layout_constraintBottom_toBottomOf="parent" | |
| app:layout_constraintStart_toStartOf="parent" | |
| app:layout_constraintEnd_toEndOf="parent" /> | |
| <TextView | |
| android:id="@+id/success_message" | |
| android:layout_width="wrap_content" | |
| android:layout_height="wrap_content" | |
| android:text="`@string/enrollment_success_message`" | |
| android:contentDescription="`@string/enrollment_success_message`" | |
| android:textSize="80sp" | |
| app:layout_constraintTop_toTopOf="parent" | |
| app:layout_constraintBottom_toBottomOf="parent" | |
| app:layout_constraintStart_toStartOf="parent" | |
| app:layout_constraintEnd_toEndOf="parent" /> |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/src/main/res/layout/dialog_enrollment_success.xml` around lines 17 - 25,
The TextView in dialog_enrollment_success.xml is using a hardcoded emoji ("🎉")
in android:text which is not accessible; replace the hardcoded text with a
string resource (e.g., add <string name="enrollment_success_message">Enrollment
successful</string> to res/values/strings.xml) and set the TextView's
android:text to that resource
(android:text="`@string/enrollment_success_message`"); ensure the TextView also
provides an accessible label for TalkBack (e.g., via android:contentDescription
referencing the same string) so screen readers receive meaningful feedback.
Changes
Ref: AJ-658
Summary by CodeRabbit
New Features
Chores