Skip to content

feat(account): show the inactive-account status and file deletion countdown - #265

Merged
altaywtf merged 4 commits into
mainfrom
feat/inactive-account-notice
Oct 1, 2026
Merged

altaywtf merged 4 commits into
mainfrom
feat/inactive-account-notice

Conversation

@altaywtf

@altaywtf altaywtf commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

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_status and files_will_be_deleted_at, so a lapsed account looked healthy until its files were gone.

  • States follow web's AccountStatusNotification: inactive reads "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's daysDiffFromNow; no message without a date). A family plan member (is_sub_account, putio-sdk-kotlin#61) reads "Your family plan is no longer active." active and stranger show nothing.
  • No billing or family link and no pay/renew/subscribe wording (Google Play payments policy). Web's "Keep a good thing going!" and "Leave the family plan" actions and its "start your own subscription" line are dropped; the family title keeps only the fact from web's "Your family plan's owner needs to update their payment details to keep your plan active." strings.xml cites each source key in web's en.json.
  • Deliberate divergence: Android plurals give "in 1 day"; web always says "days".
  • Placement: under the top bar on mobile; above the pane on TV with no focus target, so D-pad entry and Back are unchanged.

Proof:

  • Local, --max-workers=2: detekt; InactiveAccountNoticeTest (5, both surfaces), MobileInactiveAccountNoticeTest (4), PutioAuthSessionGatewayTest (5), PutioTvSessionGatewayTest (5), the notice tests in MobileShellTest and TvShellTest. CI Verify Android app is the full gate.
  • Negative controls: web's always-"days" copy fails the singular test; restoring a "Keep a good thing going!" button fails all three no-action tests; adding "Subscribe…" text fails the wording scan.
  • TV emulator (putio-tv, API 36, 1280x720): TvSafeAreaProofTest#inactiveAccountNoticeStaysInsideTheSafeArea passes with a synthetic account; screenshot below.
  • Unverified: a live inactive account (none available); the mobile notice on a device (Robolectric only).

Written by an agent (Claude Code, Opus 5.5).

…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.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@altaywtf

Copy link
Copy Markdown
Member Author

TV emulator proof (putio-tv, API 36, 1280x720): TvSafeAreaProofTest#inactiveAccountNoticeStaysInsideTheSafeArea with a synthetic inactive account whose files are deleted in 14 days. Red outline is the overscan safe area; focus is on the Files pane, and the notice takes none.

tv-239-inactive-notice

…-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.
Copilot AI balanced review requested due to automatic review settings October 1, 2026 06:53
@altaywtf altaywtf changed the title feat(account): warn when the account is inactive and files are scheduled for deletion feat(account): show the inactive-account status and file deletion countdown Oct 1, 2026
@altaywtf

altaywtf commented Oct 1, 2026

Copy link
Copy Markdown
Member Author

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). TvSafeAreaProofTest#inactiveAccountNoticeStaysInsideTheSafeArea: OK (1 test), putio-tv emulator, API 36, 1280x720, synthetic account.

Written by an agent (Claude Code, Opus 5.5).

tv-239-inactive-notice-v2

@altaywtf

altaywtf commented Oct 1, 2026

Copy link
Copy Markdown
Member Author

Local review (slopguard, Codex gpt-6.1-sol, high), final review on 0800998: one finding, rejected; no other findings.

  • Fixed in 0800998: TV notice test now presses Back from the Account pane and checks focus returns to Files with the notice still shown (backs the "Back unchanged" claim).
  • Rejected, countdown not refreshed at local midnight (raised in both runs): web computes daysDiffFromNow once inside a useMemo keyed on the account status (AccountStatusNotification.tsx#L119-L121), so a page left open overnight behaves the same; the status itself is read only at sign-in and restore (non-goal for account: warn when the account is inactive and files are scheduled for deletion #239).
  • Rejected, "pay/renew/subscribe" in comments and docs: the policy covers user-visible copy, and strings.xml names web's dropped keys to cite where each string comes from. The review agrees the rendered notice has no payment wording or actions.
  • Rejected, exercise every TV pane with the notice: no defect shown. The panes sit in a weight(1f) box under the notice, and the notice got shorter (the action row is gone).

Written by an agent (Claude Code, Opus 5.5).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 Low severity

Open (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 InactiveAccountNotice with inactiveAccountNotice() and a composable text() that renders web-parity copy and an absolute calendar-day deletion countdown.
  • New MobileInactiveAccountNotice / TvInactiveAccountNotice composables wired into MobileShell and TvShell; MobileAccount/TvAccount and 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.

@altaywtf
altaywtf merged commit d8d281d into main Oct 1, 2026
1 check passed
@altaywtf
altaywtf deleted the feat/inactive-account-notice branch October 1, 2026 07:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

account: warn when the account is inactive and files are scheduled for deletion

2 participants