The new anti-harassment features will add several different types of
filtering options through the UI.
To ensure there is no confusion, rename the existing "Filters" UI and
code to "Content filters" to accurately describe what they operate on,
distinct from new filters which will act on account metadata.
Fixes#926.
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
Previous code showed any JSON-wrapped errors from notification fetches
as the JSON string, instead of the error message.
Fix this by switching to `ApiResult` and using the formatted error
message.
Fixes 937
Previous code saved the reading position of a fully visible status. But
there are situations where no status is fully visible.
1. The user is in the middle of viewing a status longer than the screen
height, and the top/bottom of the status are off the top/bottom of the
screen.
2. The user has scrolled between two statuses. Collectively they are
longer than the screen height, and the top of one status is off the top
of the screen and the bottom of the other status is off the bottom of
the screen.
In both cases the user's reading position was not saved.
In these situations use the ID of the status closest to the bottom of
the screen, even if not fully visible. This should ensure the user never
missing anything.
Fixes#936
Previous code used `Response`. Convert to `ApiResult` as part of the
work to implement anti-harassment controls, which will need to query the
user's list of accounts they are following.
Converting just `accountFollowing` wasn't practical, as all the methods
are called by a single function in `AccountListFragment` which expects
the return type to be the same.
In rare occasions the preview card text could overlap the image if the
image had a portrait aspect ratio.
This seems to be due to the use of the `with(...) {}` scope function and
Kotlin's interoperability with Java setters.
Replace this with code that explicitly gets and sets the layout params
to ensure they are set correctly.
androidx.media3 1.4.0-rc01 and above (at the time of writing) has a bug
that breaks shared element transitions with a `PlayerView` (see
https://github.com/androidx/media/issues/1594).
This can be worked around by setting `app:surface_type="texture_view"`.
This uses more power, but for the typical length of social media videos
this shouldn't be a problem at the moment.
Fixes#920.
Previous code used `filterIsInstance<Ok<UploadEvent.FinishedEvent>>()`.
This can fail at runtime with class cast exception because the type in
`Ok<...>` is erased so `filterIsInstance` was accepting any `Ok`
`Result`. Later attempts to operate on it as a `.FinishedEvent`
generated the run time error.
Fix that by explicitly checking the type of the `Ok` result in `first`
instead.
Previous code had a bug/typo, which meant the app the user was posting
from was not shown if the app did not have an associated website. But
the bullet separating the parts of the text was still shown, resulting
in a spurious dangling bullet.
Previous code didn't set the textDirection for the status content, so
the first para of RTL text might be rendered incorrectly.
In addition, mentions and tags weren't BIDI wrapped, so would appear as
"foo@" and "foo#" in RTL statuses, instead of "@foo" and "#foo".
Fix both of these issues.
Fixes#870
Two problems with the previous code when search filters were visible:
1. The link icon overrode the tint, so didn't appear correctly in dark
and black mode.
2. The horizontal scroll view had the wrong background colour in black
mode.
Fix both, by updating the icon and adding a new style for the scroll
view.
While I'm here remove an obsolete comment and tighten up visibility.
Fixes#875
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.
Byline changes inadvertently changed how the preview image is laid out,
breaking the "Image at start, info at end" variant.
Previous code did not always show the card description if the text was
present, fix that.
Previous code set a min-height, which is no longer necessary after the
other layout changes. But it meant that a preview card with a one-line
title, no synopsis, and a URL, was taking up too much vertical space.
Previous code displayed a large placeholder icon if there was no preview
image for a preview card.
This reduces the amount of space available for the actual preview text
(i.e., title and description) and did not convey additional information
in the limited space available on the timeline.
So remove it.
While I'm here simplify the PreviewCard layout and migrate to
ConstraintLayout.