These are cached timelines, backed by Room. Room **requires** the
`PagingConfig` to have `enablePlaceholders = true`. Otherwise the list
is corrupted when scrolling down the list and paging in new items.
To restore the user's reading position correctly in the UI, wait for the
adapter to emit the very first page. Combine this with the user's
refresh key, and the number of placeholders in the page, to scroll the
user to the correct place in the list.
To make all this work, ensure that Room loads a large enough page of
data around the refresh key (in the `initialKey` calculation).
Suspect a crash is occurring in the database update on the preceding
line. Log afterwards; if the log entry is missing the crash location
is confirmed.
Previous code had legacy `try ... catch` blocks that could catch all
exceptions, including `CancellationException`, thrown if the job of a
suspending function is cancelled.
Indiscriminately catching those can interfere with cancellation, so use
`currentCoroutineContext().ensureActive()` to rethrow the exception if
the job has been cancelled.
The modifications to the Notifications* classes highlighted different
(and better) ways of writing the code that manages status timelines.
Follow those practices here.
Changes include:
- Move `pachliAccountId` in to `IStatusViewData` so the adapter does not
need to be initialised with the information. This allows the parameter
to be removed from functions that operate on `IStatusViewData`, and the
adapter does not need to be marked `lateinit`.
- Convert Fragment/ViewModel communication to use the `uiResult`
pattern instead of separate `uiSuccess` and `uiError`.
- Show a `LinearProgressIndicator` when refreshing the list.
- Restore the reading position more smoothly by responding when the
first page of results is loaded.
- Save the reading position to `RemoteKeyEntity` instead of a dedicated
property in `AccountEntity`.
- Fixed queries for returning the row number of a notification or
status in the database.
Fixes#238, #872, #928, #1190
Persist the user's notification filtering decisions (i.e., the decision
to show a filtered notification) by caching all notification data,
including the filtering decision, in the database.
## Structure changes
This means re-writing the notification management system to use Room and
the Paging library to manage the notification data.
Implement a repository and remote mediator for notifications that does
this, with knock on effects for the viewmodel and the fragment. Take the
opportunity to rewrite these to reflect (current understanding of) best
practice for state management.
Active account information is included in the viewdata for each
notification when sent to the adapter. This allows the adapter to be
created before the fragment knows the active account from the view
model.
`RemoteKeyDao` is extended to support sorting the "refresh" key for
a timeline. This is used to persist the notifications refresh key
instead of the `lastNotificationId` property in the account (which has
been removed).
## UX changes
A linear progress bar is used to show progress when notifications are
refreshed, as part of the ongoing effort to migrate the UI.
Some parts of the UI already showed lists sorted by title, but not all.
The areas fixed are:
- The list of lists in the main drawer (left side navitation)
- The list of lists when adding/removing an account from a list
Fixes#1168
Previous code managed account deletions by having specific functions to
call when an account was deleted that would delete all related data.
Replace this with proper foreign key references back to the account ID,
and cascade account deletes to the related data.
Add tests to ensure the deletes happen as expected. Update existing
tests to create an account where necessary so the new foreign key
constraints are kept.
Previous code inadvertently crashed when the user clicked on a trending
link count to see statuses about the link.
Don't do that. Instead, show the statuses that mention the link, and
show the link's title in the actionbar to make it more explicit for the
user.
Special-case this timeline type in TimelineActivity so it can't be added
to a tab (it would be difficult to distinguish it amongst tabs as they
would have the same icon).
"BKS" in the error refers to "Bouncycastle KeyStore". Remove all usage
of the Bouncycastle library from the code, re-implementing one required
function based on code from SubwayTooter. Add a license entry that
acknowledges this.
Fixes#1143
Mastodon 4.3 introduced a new API to fetch a timeline of posts that
mention a trending link.
Use that to display a "See <n> posts about ths link" message in a
trending link's preview card (if supported by the server).
Define a new timeline type with associated API call to fetch the
timeline.
Add an accessibilty action to support this.
While I'm here also support author's in preview cards that don't have a
related Fediverse account; show their name in this case.
Fixes#1123