Page MenuHomePhabricator

[L][User story] Completing / Concluding the challenge / Streak lost and cannot restart
Closed, ResolvedPublic3 Estimated Story Points

Description

User story
  • As a participant who completes 25 days, I want to receive my 15% store discount code and have the option to add a Baby Globe icon applied to my profile, so that the reward feels immediate and satisfying.
  • As a participant who did not complete 25 days, I want my best effort recognized and communicated so that I understand what my progress was.
  • As a participant whose streak has ended with insufficient days remaining to complete a restart, I want the restart option hidden, so that I'm not misled into an impossible attempt.
Requirements:

Challenge complete:

  • When a streak of 25 consecutive days is recorded, the module immediately transitions to State: Challenge complete successfully
  • Completion can occur after May 31st: a user who joins May 31st has until June 25th to complete their streak (or June 26th if a streak freeze is applied - see Nice to Have)
  • Displays a "Collect your prize" CTA on the Widget
  • Tapping "Collect your prize" opens an in-app prize screen
  • State persists until July 10th, after which the Widget is removed for all users
  • Completion is a terminal state: the system stops listening for article opens once 25 days are reached

Challenge concluded: incomplete

  • For users who do not reach 25 days with a streak that started between 1-31 May, but did read for more than 1 day in a row, they should see State: Challenge concluded: incomplete / Streak lost and cannot restart
  • Show user's highest streak achieved up until that point
  • Persist until July 10th, after which the module is removed for all users

Challenge concluded: Streak lost and cannot restart

  • Disallow re-starting the challenge if after May 31
    • After May 31st, the system stops listening for new streaks for all enrolled users who have not reached 25 days
    • If a user loses their streak after May 31, they should see State: Challenge concluded: incomplete / Streak lost and cannot restart

Challenge concluded: No streak

  • For users who never joined, or joined and never read more than 1 day in a row starting with a start date of 1-31 May, they should see State: Challenge concluded: No streak
  • Persists until July 10th, after which the module is removed for all users

Prize screen

Designs

Event Timeline

HNordeenWMF triaged this task as Medium priority.
HNordeenWMF updated the task description. (Show Details)
WRai-WMF renamed this task from [User story] Completing/Concluding the challenge to [L][User story] Completing/Concluding the challenge.Mar 2 2026, 8:05 PM
HNordeenWMF renamed this task from [L][User story] Completing/Concluding the challenge to [L][User story] Completing/Concluding the challenge/Streak lost and cannot restart.Mar 3 2026, 11:00 PM
HNordeenWMF updated the task description. (Show Details)
HNordeenWMF renamed this task from [L][User story] Completing/Concluding the challenge/Streak lost and cannot restart to [L][User story] Completing / Concluding the challenge / Streak lost and cannot restart.Mar 3 2026, 11:10 PM
HNordeenWMF updated the task description. (Show Details)
HNordeenWMF updated the task description. (Show Details)
Dbrant changed the point value for this task from 8 to 3.Mar 17 2026, 4:25 PM

@Dbrant I realized this wasn't 100% clear so checking:

Users should be able to access the prize screen any time from the Widget, once it's in the Challenge complete state. Is that how it was implemented?

Testing Instructions

  1. Go to Reading Challenge Widget Configurations in Developer Settings.
  2. Enroll if you’re not already enrolled.
  3. Update readingChallengeEndDate to a date before today and save.
  4. Navigate back, then return to the screen.
  5. Update the streak count.

Now, depending on the streak count the widget state will update.

@WRai-WMF @Dbrant this looks good to me and the button is now leading to the collect prize screen, but now that i'm able to see the prize screen i'm noticing that the sheet doesn't align with what we have in figma. can we align the visual design:

Screenshot 2026-04-07 at 2.03.05 PM.png (1×1 px, 985 KB)

  1. drag handle should be centered and anchored to the top of the sheet
  2. remove extra "%" from button and description
  3. anchor button to the bottom of the sheet, like we typically do (16px from navbar)

thank you!

  1. drag handle should be centered and anchored to the top of the sheet
  2. remove extra "%" from button and description
  3. anchor button to the bottom of the sheet, like we typically do (16px from navbar)

Whoops, how'd that happen? Anyway, these should all be fixed now:
https://github.com/wikimedia/apps-android-wikipedia/actions/runs/24099812661/artifacts/6313643696

Testing Instructions
Steps to download the APK
Feature branch: https://github.com/wikimedia/apps-android-wikipedia/pull/6367
Click on "Checks" -> find "Android branch build" -> scroll down and find "Artifacts" -> Download the "app_alpha_release" file.

  1. Go to Reading Challenge Widget Configurations in Developer Settings.
  2. Enroll if you’re not already enrolled.
  3. Update readingChallengeEndDate to a date before today and save.
  4. Navigate back, then return to the screen.
  5. Update the streak count.

Now, depending on the streak count the widget state will update.

Seddon raised the priority of this task from Medium to High.Tue, Apr 21, 4:44 PM
ABorbaWMF subscribed.

Testing on 50580-alpha-2026-04-21

On both my test devices, when I tap 'collect your prize' in the widget, the app opens, but nothing happens. I do not see the discount code or baby globe. Tapping outside of the button presents the discount code.

Testing Pre-requisites

  1. In developer settings navigate to Reading Challenge Widget Configurations
  2. Set readingChallengeStartDate to today’s date (or any date before today), and save the change to activate the challenge.
  3. Ensure the following toggles are turned off:
    • readingChallengeEnrolled
    • readingChallengeOnboardingShown
    • readingChallengeInstallPromptShown
  4. After applying the changes, restart the app to trigger and view the onboarding flow.
  5. Alternatively, you can set readingChallengeEnrolled to skip the onboarding flow. Note: if you do this, make sure readingChallengeOnboardingShown and readingChallengeInstallPromptShown are turned off.
  6. Add the widget to home screen.
  7. Set readingChallengeEndDate to a date earlier than today's date so the widget goes into concluded state.

Dev Settings Options (Explanation)

  1. readingChallengeStreak: Adjust this value to increase or decrease the streak displayed in the widget.
  2. readingChallengeEnrolled: Enable this if you want to enroll the user directly without going through the onboarding flow.
  3. readingChallengeOnboardingShown: Keep this turned off to ensure the onboarding announcement is shown.
  4. readingChallengeInstallPromptShown: Keep this turned off to display the widget installation prompt.
  5. readingChallengeLastReadDate: Modify this to simulate different reading scenarios, such as missed days or streak resets.
  6. readingChallengeStartDate: Defines the start date of the challenge. Set it to today or an earlier date and save the update.
  7. readingChallengeEndDate: Defines the end date of the challenge. Make sure to save after updating.

Looks good on 50581-r-2026-04-27
Tested on:
Pixel 6 on Android 16
OnePlus 8 on Android 13

Scenario 3 is not updating as I expect for this requirement. Not sure if it's an issue with my testing, or the logic.

Completion can occur after [May 31st]: a user who joins [May 31st] has until [June 25th] to complete their streak

The essence is that if I have an ongoing streak that began before the challenge end period, I should be allowed to finish it, past the challenge end period. That is why we have the long buffer period before removing the widget form app.

Scenario 1: coming into the end of a challenge with no streak

  • ReadingChallengeStreak = 0
  • LastReadDate = 3 days ago
  • ChallengeEndDate = Yesterday
  • Widget correctly updates to "Challenge concluded"

Scenario 2: The last day of the challenge with an ongoing streak

  • ReadingChallengeStreak = 12
  • LastReadDate = Yesterday
  • ChallengeEndDate = Today
  • Shows "Not read yet today"**, I can keep going after end date
  • Read today
  • Widget updates

Scenario 3: Day after the last day of challenge with an ongoing streak

  • ReadingChallengeStreak = 12
  • LastReadDate = Yesterday
  • ChallengeEndDate = Yesterday
  • Shows "Challenge concluded" with streak number

Expected:

  • Shows "Not read yet today"**, I can keep going after end date
  • Read today
  • Widget updates

Scenario 4: coming into the end of the the challenge with a previous streak

  • ReadingChallengeStreak = 12
  • LastReadDate = 3 days ago
  • ChallengeEndDate = Yesterday
  • Widget correctly updates to "Challenge concluded" and shows my 12 days

Hi @HNordeenWMF,
The current logic transitions to the conclusion state right after end date, with no ongoing state allowed until remove date.
When building the state logic, I followed the condition list as written:

Challenge concluded: incomplete — joined + current date after May 31st + streak of 25 days not reached

For users who do not reach 25 days with a streak that started between 1-31 May, but did read for more than 1 day in a row, they should see State: Challenge concluded: incomplete / Streak lost and cannot restart

This led me to read the start date to end date window as the full period in which the challenge could be completed, so anyone who hadn't reached 25 days by the end date would transition to concluded.
But this doesn't really work with the rule that says a user joining May 31st has until June 25th to finish. So this was my misinterpretation, and I'll fix the logic.

Confirming the logic

  1. Users who joined between the challenge start and end date and have not yet completed 25 days can continue their active streak past the end date, up until the widget removal date
  2. If their streak breaks past the end date, they transition to "Challenge concluded: incomplete / Streak lost and cannot restart" and cannot start a new streak.

Hi @WRai-WMF, Apologies. Reading those now, I agree how it could be interpreted that way. For those, I should've clarified that they don't have an active streak at the end of the challenge.
Your confirmed logic is correct.

A little bit of the "Why" behind this: Comms will be marketing the app throughout the entire month (May 18 - June 18). We would like someone who downloads the app say June 10 to still be able to finish their streak.

okay thank you. While reviewing this I found another edge case to flag:

What should the widget show to users who installed it but never enrolled, once the end date has passed? Right now they'd still see the enroll now CTA, but enrolling at that point would immediately drop them into ChallengeConcludedNoStreak. Instead should we show ChallengeConcludedNoStreak directly?

Great flag, yes after the end date, those users should immediately see ChallengeConcludedNoStreak

For users who never joined, or joined and never read more than 1 day in a row starting with a start date of 1-31 May, they should see State: Challenge concluded: No streak

Wokring for me on 50583-r-2026-04-30
Tested on:
Pixel 6 on Android 16
OnePlus 8 on Android 13

Used these steps:
Scenario 3: Day after the last day of challenge with an ongoing streak

ReadingChallengeStreak = 12
LastReadDate = Yesterday
ChallengeEndDate = Yesterday
Shows "Challenge concluded" with streak number
Expected:

Shows "Not read yet today"**, I can keep going after end date
Read today
Widget updates