Ask for a review at two earned moments instead of on every load - #560
Merged
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b20dfa764c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
The review request sat in onLoadSuccess, which is reached by more than a user opening a document: reloadUri drives it when edit mode is entered and when it is left, and PageView hands a file back through loadUri while the user is reading. So toggling edit mode twice asked twice, mid-task. Gate it on a fresh open. loadUri takes a freshOpen flag, reloadUri clears it, and onLoadSuccess only asks when the load was one the user asked for. Saving still counts, because onSaveSuccess reloads through loadUri - that one is a success the user just caused, and worth asking after. Add the landing screen as the second moment, for people who open the app and browse rather than arriving with a document from another app. Both are counted in UsageCounters and neither asks until the third open. A fresh install has nothing to say about the app yet, and asking anyway costs stars - one of the one-star reviews in the play console is literally "not used it but asking for a review". A counter rather than the length of the recently opened list: that list is capped, pruned and deletable, so it undercounts returning users, and it counts distinct documents rather than visits. requestInAppRating moves out of DocumentFragment into nonfree/InAppReview so both call sites share it, which is also where the play dependency belongs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E1ANEeai87KtnX5pBzgDEJ
Tapping the launcher while the task is still alive resumes MainActivity instead of creating it, so a flag set in onCreate missed exactly the users who keep the app in recents - the ones most likely to have something to say. Count in onStart instead, when the landing screen is what is on show. Coming back from the document picker also lands there, so the picker marks itself before it starts and that return is not counted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E1ANEeai87KtnX5pBzgDEJ
andiwand
force-pushed
the
feat/in-app-review-gating
branch
from
August 2, 2026 19:17
b20dfa7 to
34a5cda
Compare
andiwand
enabled auto-merge (squash)
August 2, 2026 19:22
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #559. That PR restored the review request in lite; this one fixes when it fires.
The problem
onLoadSuccessis reached by more than "the user opened a document":MainActivity.loadUri(intent, picker, recent list)onStart()replay — result arrived while stoppedEditActionModeCallback:35→reloadUri(true)EditActionModeCallback:59→reloadUri(false)onSaveSuccess→loadUri(...)PageView.sendFile→loadUri(...)Toggling edit mode twice asked twice, while the user was working.
The change
loadUritakes afreshOpenflag,reloadUriclears it, andonLoadSuccessonly asks when the load was one the user asked for.PageView.sendFilepassesfreshOpen = false.Saving still counts, because
onSaveSuccessreloads throughloadUri— that's a success the user just caused. So "keep it on save, drop it on enter/exit" falls out of one condition rather than three special cases.The landing screen becomes the second moment, for people who open the app and browse rather than arriving with a document from another app.
The threshold
Both moments are counted in the new
UsageCounters, and neither asks until the third open. A fresh install has nothing to say yet, and asking anyway costs stars — one of the 1★ reviews in the console is literally "not used it but asking for a review".A counter rather than the length of the recently opened list: that list is capped, pruned and user-deletable, so it undercounts exactly the returning users this is meant to find, and it counts distinct documents rather than visits.
MINIMUM_OPENSis one constant if 3 turns out to be the wrong number.requestInAppRatingmoves out ofDocumentFragmentintononfree/InAppReviewso both call sites share it — also where the Play dependency belongs.Notes
in_app_review_eligible/_error/_start/_donenow report from lite too, which is the visibility that would have caught the v4.2 regression.Verification
spotlessCheck,assembleLiteDebug,assembleProDebug,lintProDebugandtestProDebugUnitTestpass locally. The flow itself can't be exercised off a Play install —requestReviewFlow()fails into the existingin_app_review_errorbranch — so this is reviewed by reading, not by running.🤖 Generated with Claude Code