feat(profiles): populate the switch profile list - #21811
criticalAY wants to merge 5 commits into
Conversation
Loads the active profile without throwing, so a caller can fall back to the base context. Throwing during attachBaseContext would stop the app from starting at all. Timber is not planted that early, so the failure is recorded in attachError for the caller to log once logging is available. No caller yet.
Users with only the Default profile are unaffected: the wrapper delegates every override to the base context for that profile. Logging is not available this early, so any attach failure is logged once Timber is planted.
createOrNull built a ProfileManager that attachBaseContext used only for its context and then dropped, so callers had no way to reach the active profile. The manager cannot live in a static field: lint rejects that with StaticFieldLeak because ProfileManager holds a Context. An instance field on the Application is process scoped and allowed.
38f02ef to
46cf2bf
Compare
The list was a hardcoded empty flow. It now maps ProfileManager.getAllProfiles() into the UI model, so the screen shows the real profiles. The registry is backed by SharedPreferences, which has no defined iteration order, so profiles are sorted by name to keep the list stable across launches. Assisted-by: Claude Opus 5
46cf2bf to
8191492
Compare
|
Snapshot diff report vs
All 1 changed screenshotsPreferencesScreenshotTest
|
| checkNotNull(AnkiDroidApp.instance.profileManager) { | ||
| "the profile environment failed to load, see ProfileManager.attachError" | ||
| }, |
There was a problem hiding this comment.
Do we want to handle this error without crashing, or is it a developer-level assertion?
| @Before | ||
| fun setUp() { | ||
| context = ApplicationProvider.getApplicationContext() | ||
| prefs.edit(commit = true) { clear() } |
There was a problem hiding this comment.
should do this in After as well
| private fun ProfileManager.profileItems(): List<ProfileItem> = | ||
| getAllProfiles() | ||
| .map { (id, metadata) -> ProfileItem(id = id, name = metadata.displayName.value) } | ||
| .sortedBy { it.name } |
There was a problem hiding this comment.
This matches Anki Desktop: lowercase profile names are at the bottom of the list
We should encode this in tests, with a quick discussion on whether this makes sense (I prefer case in
Question: DisplayName does not seem to have Anki Desktop's uniqueness check - could you link it in the docs if I missed the reference, or could we consider implementing it if possible.
2 profiles in Anki Desktop which differ in case are not allowed on my MacBook (likely due to a potential directory conflict on Windows)
Note
Assisted-by: Claude Opus 5 (commit 1 of this PR)
Purpose / Description
Blocked by feat: profile attachBaseContext #21809
The profile screen from [Multi-Profile] feat: add profile dialog in Compose #21328 always showed an empty list, because the ViewModel returned a hardcoded emptyList(). feat: profile attachBaseContext #21809 loads the profile during startup but throws the manager away after taking its context, so nothing could reach it. This keeps the manager around and fills the list from the real registry.
Fixes
Approach
See commits
How Has This Been Tested?
Unit test
Learning (optional, can help others)
NA
Checklist
Please, go through these checks before submitting the PR.