Skip to content

Adjust personalized lessons language filter (GT-3097) - #4589

Open
tjohnson009 wants to merge 1 commit into
developfrom
GT-3097-Personalized-Lessons-Language-Filter
Open

tjohnson009 wants to merge 1 commit into
developfrom
GT-3097-Personalized-Lessons-Language-Filter

Conversation

@tjohnson009

Copy link
Copy Markdown
Contributor

Summary

The Lessons page currently has a single language filter shared by both the Personalized and All Lessons tabs, held only in memory (reset on app restart, and reset whenever the app language changes). This makes the two filters independent and persistent per GT-3097:

  • Independent per tab — the selection on Personalized and All Lessons no longer affect each other
  • Persisted — each tab's selection is stored in DataStore (dashboardLessonsFilterLocale / dashboardPersonalizedLessonsFilterLocale) and survives app restarts. Until the user makes a selection, each tab defaults to the app language
  • Hidden counts — the "# Lessons available" phrase is hidden in the language dropdown on Personalized (still shown on All Lessons). Counts are still used internally to hide languages with no lessons
  • Layout prep for GT-3096 — LessonFilters moved out of the header item into its own LazyColumn item, so the Featured Lessons section can be inserted between the header and the filter without restructuring

Behavior change to note

Previously, changing the app language reset the filter to the new app language. Now an explicit user selection persists through app-language changes (matching the ticket's persistence requirement and the GT-3102 behavior for tools). A tab with no explicit selection still follows the app language.

Known minor

On a tab switch, the filter briefly shows the app language until DataStore delivers the stored selection — same class of transient accepted in GT-3102 (#4587).

Coordination

The Settings.kt/SettingsTest.kt additions sit adjacent to GT-3102's (#4587); whichever PR merges second will have a trivial keep-both conflict.

Tests

  • SettingsTest: save/read/clear round-trips for both new keys
  • LessonsPresenterTest: independent selection per mode (with per-key write verification), follows app language when unset, keeps user selection on app-language change, persistence through state save & restore
  • LessonsLayoutTest: counts hidden in Personalized dropdown, shown in All Lessons
  • verifyPaparazzi passes — the layout split is pixel-identical, no golden changes

🎫 GT-3097

🤖 Generated with Claude Code

Make the Personalized and All Lessons language filters independent and
persist each selection across app restarts, defaulting to the app
language until the user makes a selection. Hide the lesson counts in the
language dropdown on the Personalized list, and split the filter into
its own list item so the Featured Lessons section (GT-3096) can be
inserted between the header and the filter.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@tjohnson009
tjohnson009 requested a review from a team September 4, 2026 20:06
@tjohnson009

Copy link
Copy Markdown
Contributor Author

PR Review (pre-merge self-review via /pr-review)

Summary

Makes the Lessons language filter independent per tab and persisted across app restarts (two new DataStore keys defaulting to app language), hides the "# Lessons available" dropdown counts on Personalized, and splits the filter into its own LazyColumn item to leave an insertion slot for GT-3096's Featured section.

✅ Looks Good

  • ktlint: clean (full ktlintCheck passed)
  • Presenter conventions: coroutine launched inside the eventSink callback (not bare in present()); the write uses launch(start = UNDISPATCHED) { withContext(NonCancellable) { … } } — the project-mandated pattern for committing state on a user action, so a save can't be dropped if composition disposes mid-write
  • Flow scoping: remember(mode) rebuilds the stored-locale flow on tab change, and remember(selectedLocaleFlow) re-keys the selected-item chain off it — no stale-flow capture
  • Settings: new keys/accessors are exact structural copies of the existing dashboardFilterLocale idiom; null = follow-app-language gives the "default on first download" requirement for free
  • Tests at all three layers: storage round-trips (SettingsTest), per-mode independence with write-key verification plus follows/keeps app-language behavior (LessonsPresenterTest), count visibility per mode (LessonsLayoutTest)
  • Layout split is inert: verifyPaparazzi passes — pixel-identical; the float-to-bottom arrangement counts from the list end, so the extra item doesn't affect it
  • Hygiene: 7 files, all on-topic; full app + base unit tests green

⚠️ Minor (accepted, not changed)

❌ Must Fix

  • None

Verdict

APPROVE — faithful to the ticket and the GT-3102 precedent, tested at every layer, zero visual regressions, and it clears the path for GT-3096.

🤖 Posted by Claude Code

@codecov

codecov Bot commented Sep 4, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.87179% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 53.30%. Comparing base (35ed24f) to head (9a01ab5).
⚠️ Report is 15 commits behind head on develop.

Files with missing lines Patch % Lines
.../godtools/ui/dashboard/lessons/LessonsPresenter.kt 88.23% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #4589      +/-   ##
===========================================
+ Coverage    53.19%   53.30%   +0.10%     
===========================================
  Files          440      440              
  Lines        11585    11612      +27     
  Branches      1960     1969       +9     
===========================================
+ Hits          6163     6190      +27     
+ Misses        4839     4838       -1     
- Partials       583      584       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

1 participant