feat(account): show the inactive-account status and file deletion countdown - #265
Conversation
…led for deletion Maps account_status, is_sub_account and files_will_be_deleted_at to web's AccountStatusNotification states and copy. Mobile shows the notice under the top bar with a link to app.put.io; TV shows it above every pane with the address as text.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…-notice # Conflicts: # app/src/mobile/kotlin/io/putdotio/android/auth/MobileAuthController.kt # app/src/mobile/kotlin/io/putdotio/android/auth/PutioAuthSessionGateway.kt # app/src/testMobile/kotlin/io/putdotio/android/auth/PutioAuthSessionGatewayTest.kt # app/src/testTv/kotlin/io/putdotio/android/tv/auth/PutioTvSessionGatewayTest.kt # app/src/tv/kotlin/io/putdotio/android/tv/auth/TvSessionGateway.kt
…account notice Google Play's payments policy rules out web's billing and family links and its pay/renew/subscribe wording. Both surfaces now show the account status and the deletion countdown as plain text; the family plan title keeps only the fact.
|
TV proof on c4d68bd: the inactive notice shows the status and the 14-day countdown above Files, with no link or action, inside the overscan safe area (red outline). Written by an agent (Claude Code, Opus 5.5). |
|
Local review (slopguard, Codex gpt-6.1-sol, high), final review on 0800998: one finding, rejected; no other findings.
Written by an agent (Claude Code, Opus 5.5). |
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
It will not compile in CI until the external SDK PR (#61) merges, and the Play payments-policy copy/scope is explicitly a release-owner call, so human review is warranted.
Review effort: Balanced
Findings: 1
What changed in this PR
This PR restores the "inactive account" warning that Android had been missing after the API fields account_status and files_will_be_deleted_at were dropped, so a lapsed/deactivated account no longer looks healthy until its files are deleted. A shared mapping in app/src/main turns AccountInfo into an InactiveAccountNotice (family-plan vs. deactivated, with a device-zone calendar-day countdown mirroring putio-web's AccountStatusNotification), and each surface lays it out: mobile under the top bar on every destination, TV above every pane as non-focusable text. The notice is intentionally facts-only (no links/actions) to stay within Google Play's payments policy. The status is read with the account at sign-in and session restore via the mobile and TV session gateways.
Changes:
- New shared model/mapping
InactiveAccountNoticewithinactiveAccountNotice()and a composabletext()that renders web-parity copy and an absolute calendar-day deletion countdown. - New
MobileInactiveAccountNotice/TvInactiveAccountNoticecomposables wired intoMobileShellandTvShell;MobileAccount/TvAccountand both gateways now carry the notice. - New strings/plurals, behavior/harness docs, and unit + shell + safe-area tests across both surfaces.
| File | Description |
|---|---|
| app/src/main/kotlin/io/putdotio/android/account/InactiveAccountNotice.kt | Core sealed model, status→notice mapping, day-count and composable text. |
| app/src/main/res/values/strings.xml | Web-sourced title, family title, and deletion-countdown plurals. |
| app/src/mobile/kotlin/io/putdotio/android/account/MobileInactiveAccountNotice.kt | Mobile banner composable (non-clickable Surface). |
| app/src/mobile/kotlin/io/putdotio/android/MobileShell.kt | Renders notice under the top bar on every destination. |
| app/src/mobile/kotlin/io/putdotio/android/auth/MobileAuthController.kt | Adds inactiveNotice to MobileAccount. |
| app/src/mobile/kotlin/io/putdotio/android/auth/PutioAuthSessionGateway.kt | Maps the notice when building the mobile account. |
| app/src/tv/kotlin/io/putdotio/android/tv/account/TvInactiveAccountNotice.kt | TV banner composable with no focus target. |
| app/src/tv/kotlin/io/putdotio/android/tv/TvShell.kt | Places notice above every pane without taking focus. |
| app/src/tv/kotlin/io/putdotio/android/tv/auth/TvSessionGateway.kt | Adds inactiveNotice to TvAccount and maps it. |
| app/src/test/.../InactiveAccountNoticeTest.kt | Unit tests for mapping and day counting. |
| app/src/testMobile/.../MobileInactiveAccountNoticeTest.kt | Mobile copy, singular/plural, family, no-action tests. |
| app/src/testMobile/.../MobileShellTest.kt | Shell-level notice presence/absence test. |
| app/src/testMobile/.../auth/PutioAuthSessionGatewayTest.kt | Family-plan notice gateway test. |
| app/src/testTv/.../TvShellTest.kt | TV notice shows above panes without taking focus. |
| app/src/testTv/.../auth/PutioTvSessionGatewayTest.kt | Inactive account carries its notice. |
| app/src/androidTestTv/.../TvSafeAreaProofTest.kt | On-device safe-area proof for the notice. |
| docs/behavior.md, docs/harness.md | Document the inactive-account behavior and TV proof. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.



Closes #239
An inactive account now shows a persistent, non-interactive notice on every signed-in screen, mobile and TV, with the account status and the file-deletion countdown. Android previously dropped
account_statusandfiles_will_be_deleted_at, so a lapsed account looked healthy until its files were gone.AccountStatusNotification:inactivereads "Your account has been deactivated 😢" plus "Your files are still here, but they are scheduled to be deleted in N days." (calendar days in the device's zone, like web'sdaysDiffFromNow; no message without a date). A family plan member (is_sub_account, putio-sdk-kotlin#61) reads "Your family plan is no longer active."activeandstrangershow nothing.strings.xmlcites each source key in web'sen.json.Proof:
--max-workers=2: detekt;InactiveAccountNoticeTest(5, both surfaces),MobileInactiveAccountNoticeTest(4),PutioAuthSessionGatewayTest(5),PutioTvSessionGatewayTest(5), the notice tests inMobileShellTestandTvShellTest. CIVerify Android appis the full gate.putio-tv, API 36, 1280x720):TvSafeAreaProofTest#inactiveAccountNoticeStaysInsideTheSafeAreapasses with a synthetic account; screenshot below.Written by an agent (Claude Code, Opus 5.5).