Long-backgrounded sessions (especially on aggressive vendors like Huawei)
could leave the Play token invalid and OkHttp's connection pool full of
dead sockets, producing a perpetual loading spinner with no error.
- ComposeActivity#onStart probes the saved token via isSavedAuthDataValid;
on failure evicts the OkHttp pool and refreshes anonymous auth.
- AuthProvider gains authReady StateFlow, awaitReady(), and a mutex-guarded
refreshAnonymousAuth() so concurrent callers don't double-fetch.
- Play-backed ViewModels (AppDetails, DevProfile, MoreApps, Reviews, Search,
ExpandedStreamBrowse, Category) await refresh completion before issuing
helper calls, closing the race between resume-time refresh and screen
LaunchedEffect fetches.
- AppDetailsScreen rendered Error as Loading when app was null; reorder so
Error wins and wire a Retry button through Placeholder.
- Stream/Review/Search/DevProfile/CategoryBrowse error placeholders gain
Retry actions wired to PagingItems.retry() or the VM's fetch.
- CategoryViewModel was logging-only on failure; now emits ViewState.Error
with a matching Retry path in CategoriesPage.
Share a sort/filter sheet between InstalledScreen and BlacklistScreen via
new commons module (SortFilterState + SortFilterSheet + applyFilter/applySort
on InstalledAppMeta), persisted per-screen. InstalledScreen renders a new
InstalledAppListItem that surfaces size, last-update, and installer instead
of Play-listing extras. Blacklisted rows now desaturate their icons.
- AppUpdateItem now shows a disabled "Installing" button while the
download is COMPLETED and awaiting install, instead of briefly
reverting to "Update" between download-done and InstallerEvent.Installed.
- Section header replaces all-or-nothing "Update all" toggle with an
any-active check, so "Cancel all" appears as soon as a single update
is in flight. Same treatment for the ownership-approval section.
- Empty placeholder no longer hides the ignored-updates list when there
are no live updates.
- DownloadHelper.cancelAll also flips COMPLETED -> CANCELLED so the
Cancel-all button gives immediate feedback for pending-install rows.
- DownloadListItem: surface the failed icon for FAILED downloads too.
Collect NetworkProvider.status once at the activity root and expose it via
LocalNetworkStatus so any screen can read it without injecting the provider.
Drop the redundant networkProvider field from MainViewModel and AuthViewModel.
NetworkSheet becomes a full-screen NetworkScreen with the same content.
- New SourceFiltersScreen with All toggle + add/remove of specific
installer package names. Backed by PREFERENCE_FILTER_INSTALLERS
(Set<String>); PREFERENCE_FILTER_AURORA_ONLY preserved as the All
switch for backward compat.
- UpdateWorker reads installer via getInstallSourceInfo (R+) / falls
back to deprecated getInstallerPackageName below.
- UpdatesPreferenceScreen: "Filter F-Droid apps" moved to Advanced;
"Filter apps from other sources" becomes a navigation row to the
new sub-screen with a state summary.
Replace the 1-24h slider with a SingleChoiceDialog listing 7 presets
(3h, 6h, 12h, 24h, 3d, 7d, 15d). Storage stays as an Int hour count
under the same preference key, so old values keep working; off-preset
values display as the nearest preset but are only overwritten when the
user picks something new.
- Group updates into main / approval-required / incompatible / ignored
- New ignored_update table (v8) with per-version skip support
- isIncompatible flag on pristine system apps for HyperOS / GrapheneOS (v7)
- requiresOwnershipTransfer() runtime check on Android 14+
- Rename AppMenuSheet -> AppUpdateSheet; drop MinimalApp, nav carries Update
- Trim AppUpdateItem (no changelog dropdown / long-click)
- Fix DownloadHelper.downloadsList recomposition flicker (stable StateFlow)
- ExportWorker is now download-only