This wasn't acting as a preference.
It presented as a switch. If the user toggled it some notification
settings were changed for all accounts.
It wasn't clear what was changed, and if the user changed some of those
settings back the switch position did not change (it couldn't, you
couldn't meaningfully represent a partial change using a single switch).
Since the user has full control over the notification filters on a
per-account basis remove this "preference" to reduce confusion.
Fixes#935
Previously, tapping a tab would jump to the top of the loaded content,
which might trigger a load of a fresh page.
Provide a preference to control this; the default is the current
behaviour, the user can also choose to discard the current content and
load the newest content.
Fixes#939
Update `DownloadUrlUseCase` with a parameter to specify the account that
"owns" the media. This is either the account that posted the status, or
the account being viewed (e.g., if downloading an account's header
image).
Add a new `DownloadLocation` enum constant to download to directories
named after that account.
Pass this information through at the call sites.
Fixes#938
Provde an `appTheme` property in `SharedPreferenceRepository` to manage
read access, simplifying calling code.
Update `PreferenceEnum.from` to check the `value` property of the enum
first.
Fixes#950
The existing code downloaded any attachments to the user's "Downloads"
folder. If the user is logged in with several accounts these downloads
will be mixed up together.
Fix this by adding a new preference that allows the user to specify the
downloads should be placed in a sub-folder per account, named after the
account.
To do this:
- Add an interface for enums that can be used as preferences, with
properties for the string resource to display and the value to store.
- Add `EnumListPreference`, a `ListPreference` that allows the user to
choose between different enum values.
- Add a `DownloadLocation` enum and preference key so the user can
choose the location.
- Add a `core.domain` module, with a use case for downloading URLs that
respect's the user's download preference. Use this use-case everywhere
that files are currently downloaded.
Fixes#938
Clean up the notification handling code and fix a lot of bugs, hopefully
without introducing new ones in the process.
Specific bugs discovered and fixed:
- The code that tried to sync notification filtering state between the
server and Pachli could fail, leaving things in an inconsistent state,
resulting in dropped notifications. Remove that code, do filtering
client-side.
- Logging out of an account would disable push notifications for all
accounts.
- If any account did not support push notifications then push
notifications were disabled for all accounts.
- If any account did not support push notifications the user was
prompted to log out of all accounts. Drop that entirely.
- The UnifiedPush library could get to a state where configuring the
notification mechanism would silently fail,
The preferences UI now has a section for notifications, showing:
- The Unified Push distributor in use (if any)
- A mechanism to change the distributor
- Per-account configuration and notification fetch details
- Battery optimisation state
General changes:
- Update to UnifiedPush library 2.4.0.
- NotificationFetcher.fetchAndShow() can now fetch a single account's
notifications, or all accounts, depending on data passed to the worker.
- Use ApiResult for `push/subscription` responses.
- Drop the "needs migration" terminology for the more specific "has push
scope", to make it clear what the issue with the account is.
Add a new set of preferences, "Lab experiments", to control features
that are under investigation and may never make it into the mainstream.
Add the first experimental feature, which reverses the order of the home
timeline, so posts are shown oldest first instead of newest first.
Mastodon now supports additional (optional) author information to show
as a byline on preview cards.
Use this (if included), to show the author's avatar, name, and link to
their profile. If tapped a click on a new `Target.BYLINE` target is
registered allowing fragments/activities to launch
`ViewProfileActivity`.
Include this as an action in `ListStatusAccessibilityDelegate`, and
provide `TrendingLinksAccessibilityDelegate` to provide accessibility
actions when viewing trending links.
Add an additional preference entry that triggers an update when tapped.
It also displays the earliest time of the next automatic update check as
the preference summary.
Move the code that performs the update check (and the logic for whether
to perform the check) out of `MainActivity` and in to `UpdateCheck` so
it's available from `PreferencesFragment`.
The existing code base is a single monolithic module. This is relatively
simple to configure, but many of the tasks to compile the module and
produce the final app have to run in series.
This is unnecessarily slow.
This change starts to split the code in to multiple modules, which are:
- :core:account - AccountManager, to break a dependency cycle
- :core:common - low level types or utilities used in many other modules
- :core:database - database types, DAOs, and DI infrastructure
- :core:network - network types, API definitions, and DI infrastructure
- :core:preferences - shared preferences definitions and DI
infrastructure
- :core:testing - fakes and rules used across different modules
Benchmarking with gradle-profiler shows a ~ 17% reduction in incremental
build times after an ABI change. That will improve further as more code
is moved to modules.
The rough mechanics of the changes are:
- Create the modules, and move existing files in to them. This causes a
lot of churn in import arguments.
- Convert build.gradle files to build.gradle.kts
- Separate out the data required to display a tab (`TabViewData`) from
the data required to configure a tab (`TabData`) to avoid circular
dependencies.
- Abstract the repeated build logic shared between the modules in to
a set of plugins under `build-logic/`, to simplify configuration of
the application and library builds.
- Be explicit that some nullable types are non-null at time of use.
Nullable properties in types imported from modules generally can't be
smart cast to non-null. There's a detailed discussion of why this
restriction exists at
https://discuss.kotlinlang.org/t/what-is-the-reason-behind-smart-cast-being-impossible-to-perform-when-referenced-class-is-in-another-module/2201.
The changes highlight design problems with the current code, including:
- The main application code is too tightly coupled to the network types
- Too many values are declared unnecessarily nullable
- Dependency cycles between code that make modularisation difficult
Future changes will add more modules.
See #291.