Commit Graph

4308 Commits

Author SHA1 Message Date
Miles Krell 1f4930ff79 fix(l10n): Update Spanish translations
Currently translated at 100.0% (606 of 606 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/es/
2024-04-27 02:08:54 +02:00
Nik Clayton 78cda01ec8
change: Adjust SwipeRefreshLayout offset in AccountActivity (#652)
The change in 5959d23d resulted in a stuck margin when scrolling up in
the account view.

Fix the `SwipeRefreshLayout` offset in a different way that doesn't have
that problem; move the spinner's start position to the top of the screen
(instead of the negative offset it normally has) and keep the same
relative offset from the end position.

Have it scale in on the drag to complete the effect.
2024-04-27 00:15:21 +02:00
Nik Clayton 93e6b38d43
feat: Update activity transitions, prepare for predictive-back (#650)
Previous code used a single animation type (slide) when transitioning,
the transition was quite slow, and didn't behave appropriately if the
device was set to a RTL writing system.

In addition, handling the back affordance didn't work well with the new
"Predictive Back" feature in Android 14

(https://developer.android.com/guide/navigation/custom-back/predictive-back-gesture).

Fix this.

## Transitions

To update the transitions the `startActivityWithSlideInAnimation()`
implementation (and associated `finishWithoutSlideOutAnimation()`) have
been replaced.

There are three transitions; `default`, `slide`, and `explode`,
represented as an enum passed to the activity intent.

The `default` transition is the activity transition from Android 14,
from the Android open source project

(https://cs.android.com/android/platform/superproject/+/android-14.0.0_r18:frameworks/base/core/res/res/anim/;bpv=1).
This is used for most transitions.

The `slide` transition is the pre-existing slide transition, with a
shorter transition time so it feels more responsive, and an RTL
implementation. This is used when there is a strong spatial component to
the navigation, for example, when going from:

- a status to its thread
- a preference menu item to its subscreen
- a filter in a list to the "edit filter" screen
- viewing your profile to editing your profile

The `explode` transition is used when the state of the app changes
significantly, such as when switching accounts.

Activities are now started with `startActivityWithTransition()` which
sets the intent and prepares the transition. `BaseActivity` checks the
intent for the transition type and makes further changes to the
transition as necessary.

## Predictive back

"Predictive back" needs to know what the back button would do before the
user interacts with it with an `onBackPressedCallback` that is either
enabled or disabled. This required refactoring some code (particularly
in `ComposeActivity`) to gather data ahead of time and enable/disable
the callback appropriately.

## Fixed bugs

- Back button wasn't stepping back through the tabs in AccountActivity
- Modifying a filter and pressing back without saving wasn't prompting
the user to save the changes
- Writing a content warning and then hiding it would still count the
text of the content warning toward's the post's length

## Other cleanups

- Use `ViewCompat.setTransitionName()` instead of setting the
`transitionName` property
- Delete the unused `fade_in` and `fade_out` animations.
- Use androidx-activity 1.9.0 to get the latest predictive back support
library code
- Show validation errors when creating / editing filters
2024-04-26 23:18:30 +02:00
Nik Clayton 12eccb63ae
refactor: Prefer System.currentTimeMillis() to Date().getTime() (#645)
Avoids unnecessary object creation.

Add a lint rule to catch this.
2024-04-24 12:07:05 +02:00
Nik Clayton 3e1d94ded2
feat: Use Let's Encrypt certificates on API 23 devices (#640)
Android 7 devices no longer trust certificates issued by Let's Encrypt
(see https://letsencrypt.org/2020/11/06/own-two-feet and
https://letsencrypt.org/2023/07/10/cross-sign-expiration.html for
details).

To work around that provide the Let's Encrypt root certs as resources.

On API 24+ devices add those via network_security_config.xml.

On API 23 devices they need to be installed manually for OkHttp SSL
connections, and checked when there is an SSL error in
LoginWebViewActivity.

The root certificates were downloaded from
https://letsencrypt.org/certificates/:

- https://letsencrypt.org/certs/isrgrootx1.der (self-signed)
- https://letsencrypt.org/certs/isrg-root-x1-cross-signed.der
(cross-signed)
- https://letsencrypt.org/certs/isrg-root-x2.der (self-signed)
- https://letsencrypt.org/certs/isrg-root-x2-cross-signed.der
(cross-signed)

Fixes #638
2024-04-24 10:32:50 +02:00
Miles Krell 4fdb997d7e fix(l10n): Update Spanish translations
Currently translated at 100.0% (606 of 606 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/es/
2024-04-23 22:25:56 +02:00
Nik Clayton 5959d23d89
change: Move SwipeRefreshLayout margin in AccountActivity (#642)
AccountActivity is full screen, so the swipe spinner was appearing very
close to the top system bar. Adjust the spinner's top margin to avoid
the system bar, and have it scale in/out so it doesn't appear to slide
out from an invisible barrier.
2024-04-23 15:58:32 +02:00
Nik Clayton b3bce36ccc
fix: Improve transitions in/out of playing video (#636)
Previous code didn't trigger the transition from `ViewMediaActivity`
when playing a video until the video had loaded. If the connection was
slow or had other issues this resulted in the video "sticking" in the
timeline until it loaded.

Change this, and trigger the transition immediately.

Fixes #598

While looking at this:

- Save the play/pause state of the video during a swipe, pause the
video, and restore the state when the swipe is cancelled.
- Transition the entire video view, to improve the animated transition
back to the activity.
- Remove the custom progress spinner, use the one provided by the
player.
- Display the player controller via the layout XML instead of code
2024-04-23 11:35:11 +02:00
Nik Clayton aa930f3a6f
feat: Fetch more trending posts, links, and hashtags (#634)
The previous code didn't set a limit for the number of posts, links, and
hashtags to fetch on the trending pages, so used the conservative
defaults.

Increase these to the API maximums to show the user more information.
2024-04-22 21:34:22 +02:00
Nik Clayton b0d63e4243
fix: Update PageCache to handle non-chronological ordering (#633)
The PageCache implementation wasn't properly dealing with timelines that
could return statuses in non-chronological order.

For example, if you bookmark a recent status, then go back in the
timeline and bookmark an older status; the bookmarks timeline is ordered
by the time of the bookmark event, not the creation time of the status
that was bookmarked.

If a sufficiently old status was bookmarked so it straddled a page
boundary you could have a situation where the range of status IDs in two
different cached pages overlapped.

E.g., this log extract:

```
0: k: 110912736679636090, prev: 3521487, next: 3057175, size: 40, range: 112219564107059218..110912736679636090
1: k: 111651744569170291, prev: 3049659, next: 2710596, size: 40, range: 111926741634665808..111651744569170291
```

The range of IDs in page 0 overlaps with the range of IDs in page 1.

The previous `PageCache` assumed this couldn't happen, and broke in
various interesting ways when it did.

E.g., you can't find the page that contains a given status by looking
for the largest key less than the needle's status id. Given the pages
above looking for ID 112219564107059218 (first status in page 0) would
suggest page 1 as having the greatest key less than that ID. This
manifested as the correct page briefly appearing in the UI (page 0),
then being completely replaced with page 1.

Rewrite PageCache to fix this. The previous implementation used a single
`TreeMap` assuming items were always sorted by ID. The new code keeps an
unordered map from status IDs to the page that contains that status, and
a separate `LinkedList` that contains the pages in order they're
provided by the API. This decouples the ordering of pages in the cache
with the overall ordering of items within the pages.
2024-04-22 20:34:16 +02:00
Nik Clayton b8939dd2cf
fix: Ensure actionbar title is set correctly (#628)
https://github.com/pachli/pachli-android/pull/589 changed the initial
setting of the action bar title to use `binding.mainToolbar.title`
instead of `supportActionBar?.title`.

Not sure why, but this doesn't work on first use, and was showing
"Pachli Current" until the user changes tabs. Swap one usage back to
`supportActionBar?.title` to fix this, and update the other to do the
same thing to keep the code consistent.
2024-04-15 22:42:22 +02:00
Nik Clayton 7752cf9210
fix: Set correct text direction for localised error messages (#601)
Use `unicodeWrap` when inserting placeholders in error messages so they
set the correct text direction.

Update some strings with formatting directives to (a) include `_fmt`
in the name, and (b) use `%1$s` instead of `%s`.
2024-04-09 14:26:15 +02:00
Weblate (bot) 9e35147658
fix(l10n): Translations update from Hosted Weblate (#588)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for [Pachli/Fastlane
Metadata](https://hosted.weblate.org/projects/pachli/fastlane-metadata/).


It also includes following components:

* [Pachli/Core/Network :
Main](https://hosted.weblate.org/projects/pachli/corenetwork-main/)

* [Pachli/App :
Main](https://hosted.weblate.org/projects/pachli/app-main/)

* [Pachli/Feature/About :
Main](https://hosted.weblate.org/projects/pachli/featureabout-main/)

* [Pachli/Feature/Lists :
Main](https://hosted.weblate.org/projects/pachli/featurelists-main/)

* [Pachli/App :
Google](https://hosted.weblate.org/projects/pachli/app-google/)

*
[Pachli/Feature/Login](https://hosted.weblate.org/projects/pachli/featurelogin/)

* [Pachli/Core/Designsystem :
Main](https://hosted.weblate.org/projects/pachli/coredesignsystem-main/)

* [Pachli/Core/Activity :
Orange](https://hosted.weblate.org/projects/pachli/coreactivity-orange/)

* [Pachli/Core/Activity :
Main](https://hosted.weblate.org/projects/pachli/coreactivity-main/)

* [Pachli/App :
Fdroid](https://hosted.weblate.org/projects/pachli/app-fdroid/)

* [Pachli/Core/Ui :
Main](https://hosted.weblate.org/projects/pachli/coreui-main/)



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/pachli/fastlane-metadata/horizontal-auto.svg)

---------

Co-authored-by: ButterflyOfFire <boffire@users.noreply.hosted.weblate.org>
Co-authored-by: Kalle Kniivilä <kalle.kniivila@gmail.com>
Co-authored-by: Nik Clayton <nik@ngo.org.uk>
2024-04-05 17:52:39 +02:00
Nik Clayton b52ec248b0
refactor: Remove unnecessary whitespace in poll_info_format resource (#595) 2024-04-05 16:46:38 +02:00
Angelo Suzuki 6507e2bec1
fix: Setup compose button when creating MainActivity (#589)
The compose button isn't initially working on `MainActivity`. It is only
properly setup after changing tabs.

Fix by calling `MainActivity.refreshComposeButtonState(TabViewData)` on
creation.
2024-04-04 13:33:43 +02:00
Nik Clayton 6bef6f2fae
feat: Simplify adding/removing timelines from tabs (#587)
Previously, modifying any tabs meant opening the left-side nav, opening
Account preferences > Tabs, and then adding / removing tabs. This is
time consuming, and difficult for new users to discover.

In addition, it was possible to remove the Home tab, and there was a
hardcoded minimum of at least two tabs.

Fix this.

When viewing a timeline that is not already in a tab an "Add to tab"
menu item is enabled, which appends the timeline to the list of existing
tabs.

When viewing a timeline in a tab (that is not the Home timeline) a
"Remove tab" menu item is enabled, which removes the tab from the list
of existing tabs.

If the user removes the active tab (either with this menu item, or
through preferences) the tab to the left of the active tab becomes the
new active tab.

A new "Manage tabs" menu item is also provided, as a shortcut to the
existing Account preferences > Tabs screen.

When managing tabs the Home timeline can not be removed; the button to
remove it is removed, and swiping is disabled on that list item. The
restriction of "at least two tabs" has also been removed.

`NotificationsActivity` has been removed, as `TimelineActivity` can
display `NotificationsFragment`.

To make the three "Trending" types (hashtags, links, and posts) more
visually distinct add two new icons for links (ic_newspaper) and posts
(ic_whatshot).

Fixes #572, #584, #585, #569
2024-04-03 00:10:09 +02:00
Nik Clayton 0829d91989
fix: Stop crash in FollowedTagsActivity when view is not created (#586) 2024-04-02 17:51:46 +02:00
Nik Clayton 4ea42f4a2c
feat: Add left-nav entries for Local, Federated, and Direct Messages (#583)
Fixes #570
2024-04-01 21:42:28 +02:00
Nik Clayton d65d969257
fix: Allow filter expiration to be set to "indefinite" (#582)
Mastodon API uses an "empty" `expires_in` value for a filter to mean
"Does not expire" (i.e., indefinite).

This was modelled as a null. Which doesn't work, because Retrofit does
not send name/value pairs in encoded forms if the value is null.

Fix this by making the API type a `String?`, and explicitly using the
empty string when indefinite expiry is used. This has to be converted
back to an Int? in a few places.

See
https://github.com/mastodon/documentation/issues/1216#issuecomment-2030222940
2024-04-01 20:48:11 +02:00
Nik Clayton c45408088a
refactor: Use the `minutes` helper to create the duration (#581) 2024-04-01 20:14:19 +02:00
Nik Clayton 55c12dde44
refactor: Improve show/hide FAB logic (#580)
Previous code was inconsistent about how and when the FAB was hidden if
the user had set the relevant preference.

- Sometimes the FAB has hidden by setting the visibility to false, which
removed it with no animation.

- Sometimes the value of the preference was checked once, when the
fragment or activity was created.

- Some timelines didn't show the FAB (Hashtags, Favourites, Bookmarks,
TrendingLinks, TrendingStatuses).

- Logic for figuring out which `ComposeActivity` intent to use was
scattered across different files.

Improve this by:

- Expose changes to the `FAB_HIDE` preference in the relevant viewmodels
as a flow the UI component can collect.

- Centralise the show/hide logic in a new `ActionButtonScrollListener`
class, and always using `show()`/`hide()` to animate the transition.

- Centralise the logic for creating the `ComposeActivity` intent in
`TabViewData`.
2024-04-01 19:57:46 +02:00
Nik Clayton 53fa56bbb4
feat: Support adding "Favourites" to a tab (#578) 2024-03-31 00:03:32 +01:00
Nik Clayton 64fae0ceb6
refactor: Rename `StatusListActivity` to `TimelineActivity` (#577)
More accurately reflects what it does, and simplies the diffs for
upcoming work.
2024-03-30 23:48:04 +01:00
Nik Clayton 8257ded395
refactor: Remove `TabData` type (#576)
`TabData` recorded the type of the timeline the user had added to a tab.
`TimelineKind` is another type that records general information about
configured timelines, with identical properties.

There's no need for both, so remove `TabData` and use `TimelineKind` in
its place.

`TimelineKind` is itself mis-named; it's not just the timeline's kind
but also holds data necessary to display that timeline (e.g., the list
ID if it's a `.UserList`, or the hashtags if it's a `.Hashtags`) so
rename to `Timeline` to better reflect its usage. Move it to a new
`core.model` module.
2024-03-30 23:27:25 +01:00
Nik Clayton 09ca6ae0a8
fix: Create a dedicated menu for NotificationsActivity (#571)
Previous code (probably copy/paste error) used R.menu.activity_trending.
2024-03-29 21:37:45 +01:00
Nik Clayton c2db3dfbcc
chore: Prepare release 2.4.0 (versionCode 13) (#568) 2024-03-28 11:46:06 +01:00
Nik Clayton 0bb269a37d
fix: Don't crash on invalid avatars (#566)
Workaround a Glide bug where the error() handler is not always called,
in this case when the URL does not resolve to an image; for example, a
misconfigured server that redirects requests for the image to an HTML
page.

Catch the exception and use the default avatar image in these cases.
2024-03-24 19:32:28 +01:00
Nik Clayton d3c7c7c89a
fix: Surface all exceptions to the user instead of crashing (#565)
Previous code would handle some expected exceptions (IO, HTTP) when
fetching a timeline, and show them to the user. Any other exception
would crash.

Now, surface all exceptions. Treat IO and HTTP exceptions as retryable
and show the "Retry" option, all others are considered non-retryable.

Provide a specific error string for exceptions caused by bad JSON.
2024-03-24 18:36:28 +01:00
Nik Clayton 2a4126a542
fix: Improve URL / tag / mention extraction when composing (#564)
Previous code used custom regular expressions to extract URLs, hashtags,
and mentions from text while the user was writing a post. These were
inconsistent with the ones that Mastodon uses so the derived character
count could be wrong.

As well as being visually incorrect this could prevent the user from
posting a status that was within the length limit, or allow them to
attempt to post a status that was over the length limit (which would
then fail).

Fix this by dropping the homegrown regular expressions and using the
same text parsing library that Mastodon users; twitter-text. This has
been converted to Kotlin and the functionality related to Twitter
specific features has been removed.

The hashtag handling has been adjusted, as Mastodon is more permissive
about the positions where hashtags can appear than Twitter is, in
particular, a hashtag does not need to be preceded with whitespace if
the tag appears after some scripts, such as Hirigana.
2024-03-23 14:14:07 +01:00
Kalle Kniivilä d75c4354bb fix(l10n): Update Finnish translations
Currently translated at 100.0% (594 of 594 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/fi/
2024-03-21 17:43:55 +01:00
Nik Clayton 783d4e5cca
feat: Notify the user about severed relationships (#557) 2024-03-21 17:27:48 +01:00
Nik Clayton 8ef227fd20
fix: Improve accessibility of ComposeActivity bottomsheets and buttons (#548)
The previous bottomsheets did set a minimum height for the menu items,
so they were less than the recommended 48dp minimum. Fix that to improve
the overall accessibility.

Always highlight the "visibilty" icon, to make it clear that it's
something that is set (even if to the default).

Show the visibility icon on the "Toot" button as an additional reminder
to the user.

Other changes:

- Use the "filled" style for all icons (the visibility icons had the
"outlined" style)

- Use the `makeIcon` helper function.

- Use the `Status.Visibility` extension functions to determine the icon
for each visibility type, reducing code duplication.
2024-03-21 16:24:31 +01:00
Nik Clayton 778017475d
revert: Allow "Vote" button to expand to contain text (#545)
Expanded too far...
2024-03-19 19:02:15 +01:00
Nik Clayton ae811d7126
refactor: Allow "Vote" button to expand to contain text (#545) 2024-03-19 18:00:42 +01:00
Nik Clayton bcceaaa434
feat: Show the post's language tag in the detailed view (#546) 2024-03-19 18:00:33 +01:00
Nik Clayton c2fc3d1f08
feat: Allow user to see poll results before voting (#543)
Show a labelled checkbox to the bottom-right of polls that the user has
not voted in and that have votes. If checked the current vote tally (as
percentages) will be shown, along with a bar showing the relative value
of each option.
2024-03-19 13:23:21 +01:00
Kalle Kniivilä 4ca43e1c2e fix(l10n): Update Finnish translations
Currently translated at 100.0% (593 of 593 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/fi/
2024-03-18 19:31:42 +01:00
Nik Clayton 9e0a1f4015
refactor: Simplify use of BackgroundMessageView (#539)
Previous code expected callers to typically provide the drawable and the
error message string resource, resulting in duplicate code at many
callsites.

Replace with three canned messages for empty containers, generic errors,
and network errors respectively. The images for these are fixed, the
caller may choose a different string resource for the error if there is
a more specific option.

Update and simplify the call sites.
2024-03-16 22:12:54 +01:00
Nik Clayton e41722e16f
refactor: Extract user list functionality to `feature:lists` (#537)
Move `ListsActivity`, along with fragments and viewmodels, to a new
`feature:lists` module.

Previous code used the `item_follow_request` layout, which was not
ideal, so update it to use a dedicated layout, `item_account_in_list`.

The UI uses strings and views originally defined in the main app, so
move them elsewhere so they can be re-used.

- `BackgroundMessageView` moves to `core.ui`.

- `Lazy` moves to `core.common`.

- `ThrowableExtensions` split; the extensions specific to throwables
from network activity move to `core.network`, others move to `core.ui`.

- `BindingHolder` moves to `core.ui`

- Shared drawables and strings move to `core.ui`.
2024-03-16 18:42:11 +01:00
Nik Clayton 9535506596
fix: Catch and swallow snackbar exception (#536)
For reasons not fully understood the root of a fragment's view might not
have relevant view from the activity set as its parent. This causes
`Snackbar.make()` to throw an exception, and crash.

See https://issuetracker.google.com/issues/228215869.

For now, "fix" this by swallowing the exception. Not showing the error
is better than crashing.
2024-03-16 14:34:21 +01:00
Nik Clayton bdbe2f85c2
feat: Allow the user to set a list's replies policy (#534)
The replies policy controls whether replies from members of the list
also appear in the list.

Display the replies policy as three radio buttons when a list is created
or updated, and send the chosen replies policy via the API.

Default value if not specified is always "list", for consistency with
the Mastodon API defaults.

While I'm here:

- Ensure the list dialog layout is inflated using the dialog's themed
context
- Use a `TextInputLayout` wrapper around the list name in the list
dialog for better UX
- Simplify the dialog layout, use LinearLayout, and standard padding and
margins
2024-03-14 23:56:16 +01:00
Nik Clayton 6c970a9742
fix: Keep TabDataJsonAdapter so Moshi can deserialize in release builds (#535) 2024-03-14 20:10:34 +01:00
Nik Clayton 256c6139ac
feat: Show network activity in ListsActivity (#533)
Modify `ListsViewModel` to keep track of the number of active network
operations and export as a flow. Collect this in `ListsActivity` and
show a `LinearProgressIndicator` while it is non-zero.
2024-03-14 18:18:34 +01:00
Nik Clayton d66d9d32a4
refactor: Prune cached media using a worker (#529)
Previous code would prune any cached media every time `MainActivity` was
created, causing extra IO just as the user is trying to use the app.

Re-implement as a WorkManager worker so it can run when the device is
idle, without interfering with the responsiveness of the device.
2024-03-14 13:31:18 +01:00
Nik Clayton 6f8a3f20a9
chore: Add TODO for more specific error message in the future (#528) 2024-03-14 12:32:23 +01:00
Angelo Suzuki 5be93acf6b
feat: Improve Image Viewer toolbar auto-hide (#521)
Cancel the auto-hide behavior in case the toolbar menu items are
interacted with.

Improves https://github.com/pachli/pachli-android/issues/505,
https://github.com/pachli/pachli-android/issues/507

---------

Co-authored-by: Nik Clayton <nik@ngo.org.uk>
2024-03-13 20:19:46 +01:00
Nik Clayton d9fc664a63
refactor: Remove obsolete emoji-related resources (#526) 2024-03-13 11:29:45 +01:00
Nik Clayton cfc15c8f64
refactor: Use LinearProgressIndicator with delayed show/hide (#525)
Previous code used a normal ProgressBar and a coroutine to delay
hiding/showing the bar for a snappier UI perception.

This is built-in functionality in LinearProgressIndicator, so switch to
that.

While I'm here, implement the "Select list" dialog's layout as a layout
resource.
2024-03-13 10:03:10 +01:00
Nik Clayton 006c358053 fix: Sort lists by title wherever they occur 2024-03-12 19:52:45 +01:00
Nik Clayton 7da4bc090b fix: Update tabs when lists are renamed or deleted
If the user has tabs containing one or more lists, and any of those
lists are renamed or deleted then the change should be reflected in the
tabs.

To do that:

`MainActivity`:

- Re-create tabs whenever lists are loaded and there's a list in a tab
- Compare lists-in-tabs by the ID of the list when restoring the user's
  tab, so that a list rename doesn't lose their position.

`NetworkListsRepository`:

- Update the user's tab preferences whenever lists are loaded, removing
  tabs that contain lists that have been deleted, and updating the
  list's title for lists that have been renamed.

Fixes #192
2024-03-12 19:52:45 +01:00
Nik Clayton a973f67ac8 refactor: Store tab preferences as polymorphic JSON 2024-03-12 19:52:45 +01:00
Nik Clayton 805a2a9b1d feat: Show "Followed hashtags" menu item in left-nav 2024-03-11 21:31:34 +01:00
Nik Clayton 65a0fb19d9 feat: Tapping followed hashtag names in lists opens relevant timeline 2024-03-11 21:31:34 +01:00
Nik Clayton 4762411147
refactor: Replace custom worker factory with HiltWorkerFactory (#517)
Removes the need for a separate `WorkerModule` and factory methods in
each worker.
2024-03-11 10:49:58 +01:00
Nik Clayton 442f3bc80c
feat: Show user's lists in the left-side navigation menu (#514)
Previously to view a list the user either had to add it to a tab, or tap
through "Lists" in the navigation menu to their list of lists, and then
tap the list they want.

Fix that, and show all their lists in a dedicated section in the menu,
with a new "Manage lists" entry that's functionality identical to the
old "Lists" entry (i.e., it shows their lists and allows them to create,
delete, and edit list settings).

To do that:

- Implement a proper `ListsRepository` as the single source of truth for
list implementation throughout the app. Expose the current list of lists
as a flow, with methods to perform operations on the lists.

- Collect the `ListsRepository` flow in `MainActivity` and use that to
populate the menu and update it whenever the user's lists change.

- Rewrite the activities and fragments that manipulate lists to use
`ListRepository`.

- Always show error snackbars when list operations fail. In particular,
the HTTP code and error are always shown.

- Delete the custom `Either` implementation, it's no longer used.

- Add types for modelling API responses and errors, `ApiResponse` and
`ApiError` respectively. The response includes the headers as well as
the body, so it can replace the use of `NetworkResult` and `Response`.
The actual result of the operation is expected to be carried in a
`com.github.michaelbull.result.Result` type. Implement a Retrofit call
adapter for these types.

Unit tests for these borrow heavily from
https://github.com/connyduck/networkresult-calladapter

Additional user-visible changes:

- Add an accessible "Refresh" menu item to `ListsActivity`.

- Adding a list to a tab has a dialog with a "Manage lists" option.
Previously that would close the dialog when clicked, so the user had to
re-open it on returning from list management. Now the dialog stays open.

- The soft keyboard automatically opens when creating or editing a list.
2024-03-10 23:14:21 +01:00
Nik Clayton a4dc3b85bd
fix: Show sized placeholder for hidden account media (#516)
Previous code showed a small icon for account media that the user has
hidden.

Now determine the correct size / aspect ratio for the media and use that
to compute the placeholder (either a blurhash, or the link colour for
consistency with the view on a timeline).

Fixes #513
2024-03-10 23:13:58 +01:00
Angelo Suzuki bdf2d9329e
feat: Auto-hide Image Viewer toolbar (#507)
Previous code showed the toolbar and caption when displaying the image,
and the user has to tap the screen to dismiss it.

New code is consistent with the video viewer; the toolbar and caption
is displayed for two seconds, and then auto-hides.

- Tapping after the hide displays the toolbar and caption, which will
  not auto-hide and requires a second tap to dismiss.

- Tapping the caption before it's hidden cancels the auto-hide

Fixes #505
2024-03-10 23:13:40 +01:00
Nik Clayton 0445e187df
fix: Ensure logging out accounts completes (#515)
The account logout process could fail due to API exceptions; network
errors for example, or if the user had already revoked the app's token
for that account. This would prevent the rest of the logout process
(cleaning database, etc) from completing.

Fix this by ignoring network errors during the logout process, and
always cleaning up account content in the database.

Fix a related issue where a deleted account might be recreated in a
partial state if the account's visible position was saved after it was
deleted. The recreated account couldn't do anything as it had no tokens,
but is very confusing.
2024-03-10 12:25:12 +01:00
Nik Clayton 32a6d3465b
feat: Include "Notifications" in the left-side navigation menu (#504)
Previously the only way to access notifications was to dedicate a tab to
them. Now notifications are available from the left-side navigation menu
so they're always accessible.

Add them to the top of the list, and swap the order of bookmarks and
favourites, assuming that users are more likely to want to see their
bookmarks than their favourites.

Move "Edit profile" to the bottom with the other settings options,
assuming that editing their profile does not happen very often, so
should not be at the top of the list.
2024-03-05 14:45:28 +01:00
Juan M Sevilla 92eb9f32b7 fix(l10n): Update Spanish translations
Currently translated at 100.0% (623 of 623 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/es/
2024-03-04 20:33:08 +01:00
Nik Clayton dc23ea23d1
refactor: Remove last vestiges of rxJava (#492) 2024-03-03 17:38:32 +01:00
Nik Clayton da6e026cc6
refactor: Implement updateShortcut as a suspending function (#491)
Previously a regular function that created and subscribed to an rxJava
callable, now it's a suspending function that enforces Dispatchers.IO as
the context, launched in its own coroutine.
2024-03-03 17:21:04 +01:00
Nik Clayton 900b1728bf
refactor: Implement deleteStaleCachedMedia as a suspending function (#490)
Previously a regular function launched with an rxJava scheduler, now
it's a suspending function that enforces Dispatchers.IO as the context,
launched in its own coroutine.
2024-03-03 17:02:23 +01:00
Nik Clayton 1026fccc40
refactor: Restructure ViewMediaActivity and related fragments (#489)
Highlights:

- Implement fragment transitions for video to improve the UX, video
won't start playing until the transition completes
- Remove rxJava
- Move duplicate code in to base classes

Details:

`MediaActionsListener`:

- Move to `ViewMediaFragment` as it's used by both subclasses
- Remove need for separate `VideoActionsListener`
- Rename methods to better reflect their purpose and improve readability

`ViewMediaFragment`:

- Move duplicated code from `ViewImageFragment` and `ViewVideoFragment`
- Rewrite code that handles fragment transitions to use a
`CompleteableDeferred` instead of `BehaviorSubject` (removes rxJava).
- Rename methods and properties to better reflect their purpose and
improve readability
- Add extra comments

`ViewImageFragment`:
- Rewrite code that handles fragment transitions to use a
`CompleteableDeferred` instead of `BehaviorSubject` (removes rxJava).

`ViewVideoFragment`:

- Implement fragment transitions for video to improve the UX, video
won't start playing until the transition completes
- Manage toolbar visibility with a coroutine instead of a handler
- Add extra comments

`ViewMediaActivity`:
- Rename properties to better reflect their purpose and improve
readability
- Add extra comments

`ImagePagerAdapter`:
- Rename properties to better reflect their purpose and improve
readability
- Add extra comments
2024-03-03 16:07:39 +01:00
Nik Clayton 72e5ca887d
fix(deps): update agp to v8.3.0, lint to 31.3.0 (#483)
New lint rules highlighted a potential crash; the use of named match
groups (used here when extracting server versions) requires API >= 26 or
throws an exception.

Use the group numbers instead of names when extracting the value, but
keep the group names in the regular expressions for readability.
2024-03-01 23:07:14 +01:00
Nik Clayton b9512e49b4
fix: Ensure files are fully downloaded before sharing (#482)
The previous code would share media by either:

a. If it was an image, downloading the image using Glide in to a bitmap,
then recompressing as a PNG, saving, and sharing the resulting file.

b. Otherwise, create a temporary file, enqueue a DownloadManager request
to download the media in to the file, and immediately start sharing,
hoping that the download had completed in time.

Both approaches have problems:

In the "image" case the image was being downloaded (or retrieved from
the Glide cache), decompressed to a bitmap, then recompressed as a PNG.
This uses more memory, and doesn't share the original contents of the
file. E.g., if the original file was a JPEG that's lost (and the PNG
might well be larger than the source image).

In the second case the DownloadManager download is not guaranteed to
have completed (or even started) before the user chooses the share
destination. The destination could receive a partial or even empty file.

Fix both of those cases by always fully downloading the file before
sending the share intent. This guarantees the file is available to
share, and in its original format. Since this uses the same OkHttpClient
as the rest of the app the content is highly likely to be in the OkHttp
cache, so there will no extra network traffic because of this.
2024-03-01 21:54:30 +01:00
Nik Clayton fcae44110b
refactor: Remove synchronous search functions (#481)
The previous code used synchronous (i.e., non-suspending) functions to
call the /api/v2/search and /api/v2/accounts/search endpoints.

This is not necessary as the search was always performed in a separate
thread.

Remove, and replace their usage with the equivalent functions that
suspend.
2024-03-01 18:55:59 +01:00
Nik Clayton fb66293713
refactor: Remove duplicate strings from Filter.Action (#479)
Simplify code that users `Filter.Action` by deserialising directly into
the type instead of storing / using strings throughout the API.
2024-02-29 09:49:17 +01:00
Nik Clayton af58de5a8f
refactor: Enable core library desugaring as build convention logic (#480)
Once desugaring is enabled it needs to be enabled for up/down the
dependency chain, so enable it in the shared configuration defined by
the build convention code.

Highlighted a failing test that wasn't being run, so fix that too.
2024-02-29 09:43:44 +01:00
Nik Clayton 9a23439d04
refactor: Remove duplicate strings from Filter contexts (#478)
A filter's context (previously referred to as its `kind`) controls where
the filter is applied.

This was implemented as an enum with a specific property to control how
it would serialise when @FormUrlEncoded, and with a @Json annotation for
Moshi.

In addition, the model objects kept the filter context in its string
form throughout Pachli, requiring periodic conversion to/from the enum
type, making the code more complicated.

Fix this, by:

1. Converting the incoming JSON value to the enum type immediately, so
the rest of the code uses the enum constants exclusively.

2. Implement a Retrofit converter that serialises the enum value when
@FormUrlEncoded to the same string used in JSON serialisation
2024-02-28 19:09:54 +01:00
Nik Clayton 2aa01fba8c
chore: Prepare release 2.3.0 (versionCode 12) (#477) 2024-02-28 09:54:52 +01:00
Nik Clayton d943fa1aca
fix: Update InstanceV1/V2 related types based on real-world usage (#476)
Many servers that claim to be Mastodon-API compatible are not, as
evidenced by the content they include in the responses to
`/api/v1/instance` and `/api/v2/instance` requests.

Work around the worst of the breakage by providing defaults or marking
some fields as nullable (with a default null).

Bugs have been reported against the relevant projects.
2024-02-28 00:02:03 +01:00
Kalle Kniivilä 58a6f75728 fix(l10n): Update Finnish translations
Currently translated at 100.0% (622 of 622 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/fi/
2024-02-27 10:37:41 +01:00
Martijn de Boer 44365f445f fix(l10n): Update Dutch translations
Currently translated at 100.0% (2 of 2 strings)

Translation: Pachli/App : Google
Translate-URL: https://hosted.weblate.org/projects/pachli/app-google/nl/
2024-02-25 15:53:32 +01:00
Martijn de Boer c75c143825 fix(l10n): Update Dutch translations
Currently translated at 100.0% (622 of 622 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/nl/
2024-02-25 15:53:32 +01:00
Martijn de Boer edcf6f13ab fix(l10n): Update Dutch translations
Currently translated at 100.0% (2 of 2 strings)

Translation: Pachli/App : Fdroid
Translate-URL: https://hosted.weblate.org/projects/pachli/app-fdroid/nl/
2024-02-25 15:53:32 +01:00
Nik Clayton 51c64a74dc
fix: Parse roles without a `highlighted` property (#467)
The `highlighted` property on a role may be absent. If it is this breaks
account parsing, including accounts in an /api/v2/instance response.
This, in turn, breaks determining server capabilities, including whether
or not translation is supported.

Set the default to `true`, which matches observed Mastodon behaviour.
2024-02-22 21:17:34 +01:00
Nik Clayton 415b182405
change: Log the trigger for a refresh/reload (#466)
A user is reporting that a refresh is happening in the middle of loading
content, borne out by the existing logs.

Those logs don't say what has triggered the refresh attempt, so add
additional logging whenever a refresh can occur to record what triggered
it.
2024-02-22 17:41:56 +01:00
Nik Clayton 9071a89e48
feat: Display uncropped media on account media pages (#464)
Previously media on the "Media" tab was displayed scaled and cropped to
a square aspect ratio, effectively forcing the user to tap every image
to see it.

Now, display the images scaled but not cropped, layed out with
`StaggeredGridLayoutManager`. This shows each image in full (still
scaled) providing a better experience when scrolling down.

Scrolling up can occasionally introduce gaps in the grid as images are
re-placed as viewholders are reused. When this happens images animate to
a better position when scrolling stops.
2024-02-22 14:33:44 +01:00
Nik Clayton 203784d718
fix: Don't crash when displaying update check dialog (#463)
Previous code injected `ApplicationContext`, which is not themed, and
caused a crash if the "update" dialog was shown.

Fix by passing the necesssary context in explicitly when the check is
performed.
2024-02-22 14:16:05 +01:00
Nik Clayton 2162e03e1f
fix: Handle JSON enums with unknown values (#462)
Previous code expected all incoming enums values to map directly to
Kotlin enum constants.

This is a problem for servers with additional features -- e.g.,
"reaction" as a notification type.

Fix this with a new Moshi adapter that will set the incoming value to a
given constant if it's not recognised.

Apply this to the enum constants in core.network to ensure they are
handled.

Clean up enum handling in Converters.kt, ComposeViewModel.kt, and
Status.kt by using the existing `.ordinal` property and some extension
functions for idiomatic code.

Fixes #461
2024-02-21 23:36:24 +01:00
Nik Clayton 941f4677eb
fix: Show previews for playable audio media from accounts (#460)
Previous code showed a generic placeholder for audio media on the
account's "Media" tab.

Fix this so the preview image is shown (if it's available).

- Move the "is this attachment previewable?" code to `Attachment` so it
can be reused here.

- Restructure the logic in `AccountMediaGridAdapter` to use the new
`isPreviewable()` method when deciding whether to show a preview.

- Attachments have dedicated placeholder drawables, use those when the
preview is not available.
2024-02-20 16:20:34 +01:00
Nik Clayton 8293e90b73
feat: Allow the user to trigger update checks (#458)
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`.
2024-02-20 14:50:59 +01:00
Nik Clayton 8fdb15893a
fix: Improve legibility of stats labels for large font sizes (#457)
If the user increases the font size the labels for post statistics
(number of replies, etc) can crash in to each other.

To give more space for the text:

- Shrink the label font size
- Move the labels slightly left / tighter to the icon
- Allow the "bookmark" icon to move next to the "more" icon. There's
still 48dp of space for them, and this gives a little more space to the
other icons that have labels
2024-02-19 22:59:04 +01:00
Nik Clayton 73c947edfa
fix: Prevent crash when Friendica returns a null `voted_on` property (#456)
Friendica can return a null `voted_on` property, in violation of the API
spec.

Introduce a `BooleanIfNull` annotation that will convert the `null` to
`false` if encountered.

While I'm here update the other adapters as classes on their relevant
annotations instead of standalone classes to keep the code consistent.

Fixes #455
2024-02-19 19:04:29 +01:00
Nik Clayton 23e3cf1035
feat: Show information about notification fetches on "About" screen (#454)
Some users report that Pachli is not retrieving/displaying notifications
in a timely fashion.

To assist in diagnosing these errors, provide an additional set of tabs
on the "About" screen that contain information about how Pachli is
fetching notifications, and if not, why not.

Allow the user to save notification related logs and other details to a
file that can be attached to an e-mail or bug report.

Recording data:

- Provide a `NotificationConfig` singleton with properties to record
different aspects of the notification configuration. Update these
properties as different notification actions occur.

- Store logs in a `LogEntryEntity` table. Log events of interest with a
new `Timber` `LogEntryTree` that is planted in all cases.

- Add `PruneLogEntryEntityWorker` to trim saved logs to the last 48
hours.

Display:

- Add a `NotificationFragment` to `AboutActivity`. It hosts two other
fragments in tabs to show details from `NotificationConfig` and the
relevant logs, as well as controls for interacting with them.

Bug fixes:

- Filter out notifications with a null tag when processing active
notifications, prevents an NPE crash

Other changes:

- Log more details when errors occur so the bug reports are more helpful
2024-02-17 15:57:32 +01:00
Hosted Weblate 3fb6994429 Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/
2024-02-17 10:01:04 +01:00
JuanM b676d705bf fix(l10n): Update Spanish translations
Currently translated at 100.0% (2 of 2 strings)

Translation: Pachli/App : Google
Translate-URL: https://hosted.weblate.org/projects/pachli/app-google/es/
2024-02-17 10:01:04 +01:00
JuanM a5dc1106f0 fix(l10n): Update Spanish translations
Currently translated at 100.0% (619 of 619 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/es/
2024-02-17 10:01:04 +01:00
JuanM 90414f606b fix(l10n): Update Spanish translations
Currently translated at 100.0% (2 of 2 strings)

Translation: Pachli/App : Fdroid
Translate-URL: https://hosted.weblate.org/projects/pachli/app-fdroid/es/
2024-02-17 10:01:04 +01:00
Nik Clayton 59a7673149
fix: Use the correct font when showing inserted text (#453)
The previous code was using a bold version of the default font for
inserted text. So if the user had set a custom font it was being
ignored.

Fix this by creating a bold version of the user's typeface.

Fixes #435
2024-02-16 21:52:05 +01:00
Nik Clayton b3978c4af7
change: Move CustomFragmentStateAdapter to core.activity (#452) 2024-02-16 20:56:00 +01:00
Nik Clayton 4dbf6065fd
change: Move RefreshableFragment to core.activity (#450) 2024-02-16 19:58:11 +01:00
Nik Clayton 11bf47e3b3
fix: Handle null properties in `Attachment.Focus` (#449)
The `x` and `y` properties in `Attachment.Focus` may be null (not
documented as such, but observed in the wild).

Provide a `DefaultIfNull` adapter that can be applied to these to
replace null values with a sensible default.
2024-02-15 20:32:22 +01:00
Nik Clayton c7895cf2db
fix: Show diffs for content that doesn't start with a block element (#446)
Content that doesn't start with a block element generates a parse error.
This isn't normally seen from Mastodon servers but is seen from content
from other servers (e.g,. Akkoma), which can generate:

```
<a href="..."> some text
```

instead of:

```
<p><a href="..."> some text</p>
```

Work around this by ensuring that content-to-be-diffed is wrapped in a
`div`.
2024-02-15 14:16:50 +01:00
Nik Clayton b8ac1f3944
fix: Show correct account/timeline when composing from notifications (#445)
The previous code didn't clear the task stack or recreate `MainActivity`
when the active user was changed.

So if the user was logged in with account A and used "Compose" from a
notification sent to account B, the active account was switched to B but
the UI chrome wasn't. After exiting `ComposeActivity` they would be
looking at the timeline for account B but with a toolbar that showed
account A.

Fix this by clearing the task stack and explicitly recreating
`MainActivity` when forwarding intents to `ComposeActivity`.
2024-02-15 13:10:00 +01:00
Nik Clayton 2cf7c072ca
fix: Prevent memory leak when updating shortcuts (#443)
Shortcuts were being updated using `MainActivity.this` as the `Context`
and leaking in `ShortcutManagerCompat`. Use the application context to
fix this.
2024-02-15 00:25:37 +01:00
Nik Clayton 0d826bc2d6
fix: Don't crash when deserializing notification types (#442)
When the `Notification.Type` enum was moved to a separate module it
resulted in exceptions trying to deserialize the enum:

```
java.lang.RuntimeException: Parcelable encountered ClassNotFoundException reading a Serializable object (name = app.pachli.core.network.model.Notification$Type)
```

This happened in debug builds without Proguard, so not a minification or
renaming issue.

Fix this by providing `putEnum`/`getEnum` extension functions on
`Bundle` that store the enum's ordinal value and restore it from that.
2024-02-14 23:55:46 +01:00
Nik Clayton 913f366a41
fix: Expedite notification fetches via UnifiedPush (#440)
UnifiedPush broadcasts are used to trigger fetching new notifications.
Previously this was a normal one-time work request. Mark it as expedited
to increase the likelihood it will run soon.
2024-02-14 12:01:06 +01:00
Nik Clayton e71e0df324
fix: Allow HIDE_TOP_TOOLBAR preference text to wrap (#439)
Previously it was constrained to a single line, and would clip on narrow
devices.

Fixes #436
2024-02-14 11:31:21 +01:00
Nik Clayton 2d03e6cf7b
change: Move AlertDialogExtensions to core.ui (#438) 2024-02-14 11:26:28 +01:00
Nik Clayton 96474a9ac3
change: Improve logging calls to Timber (#430)
- Use format strings so any overhead of building the string is only
incurred if the message is actually logged

- Pass throwables as the first parameter so they are logged with the
stacktrace
2024-02-09 17:33:01 +01:00
Nik Clayton 9b0f1118f9
fix: Add missing import for MoshiConverterFactory (#431)
Add run CI on the PR not the base.
2024-02-09 17:18:50 +01:00
Nik Clayton a3d45ca9ec
refactor: Convert from Gson to Moshi (#428)
Moshi is faster to decode JSON at runtime, is actively maintained, has a
smaller memory and method footprint, and a slightly smaller APK size.
Moshi also correctly creates default constructor arguments instead of
leaving them null, which was a source of `NullPointerExceptions` when
using Gson.

The conversion broadly consisted of:

- Adding `@JsonClass(generateAdapter = true)` to data classes that
marshall to/from JSON.

- Replacing `@SerializedName(value = ...)` with `@Json(name = ...)`.

- Replacing Gson instances with Moshi in Retrofit, Hilt, and tests.

- Using Moshi adapters to marshall to/from JSON instead of Gson `toJson`
/ `fromJson`.

- Deleting `Rfc3339DateJsonAdapter` and related code, and using the
equivalent adapter bundled with Moshi.

- Rewriting `GuardedBooleanAdapter` as a more generic `GuardedAdapter`.

- Deleting unused ProGuard rules; Moshi generates adapters using code
generation, not runtime reflection.

The conversion surfaced some bugs which have been fixed.

- Not all audio attachments have attachment size metadata. Don't show
the attachment preview if the metadata is missing.

- Some `throwable` were not being logged correctly.

- The wrong type was being used when parsing the response when sending a
scheduled status.

- Exceptions other than `HttpException` or `IoException` would also
cause a status to be resent. If there's a JSON error parsing a response
the status would be repeatedly sent.

- In tests strings containing error responses were not valid JSON.

- Workaround Mastodon a bug and ensure `filter.keywords` is populated,
https://github.com/mastodon/mastodon/issues/29142
2024-02-09 12:41:13 +01:00
Nik Clayton d01c72b7d7
change: Disable SyntheticAccessor lint rule (#424)
Does not appear to be adding value, and R8 optimises the code to remove
the generated accessors.
2024-02-06 19:51:37 +01:00
Nik Clayton 5a51310af8
feat: Show a preview for playable audio attachments (#426) 2024-02-06 19:38:50 +01:00
Nik Clayton 7fc8a5fb1e
change: Update lint baseline (#427) 2024-02-06 19:23:34 +01:00
Nik Clayton 9a47e306ea
fix: Keep the screen on while media is playing (#422)
Fixes #335
2024-02-06 14:13:09 +01:00
Nik Clayton 41c702fc1b
change: Display "About" information in tabs (#420)
Previously, `AboutActivity` had buttons and links to show the privacy
policy and licenses of dependencies.

Change this to a selection of fragments in tabs, one tab each for:

- General "About" information
- Licenses
- Privacy Policy

The information shown hasn't changed, but this lays the groundwork for
including additional tabs in the future for information like server
rules, detected capabilities, or troubleshooting information.
2024-02-06 00:43:26 +01:00
Kalle Kniivilä 7c5181d5c2 fix(l10n): Update Finnish translations
Currently translated at 100.0% (619 of 619 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/fi/
2024-02-05 14:18:34 +01:00
Kalle Kniivilä ab01bbfed8 fix(l10n): Update Finnish translations
Currently translated at 100.0% (2 of 2 strings)

Translation: Pachli/App : Fdroid
Translate-URL: https://hosted.weblate.org/projects/pachli/app-fdroid/fi/
2024-02-05 14:18:34 +01:00
Nik Clayton 54d7888316
feat: Include extra logs in error reports from orange release builds (#414)
Release builds normally strip out all logging to reduce the number of
disk writes and reduce UI jank.

These logs would still be useful in user error reports from orange
builds. To preseve them:

- Implement a simple `RingBuffer`.

- Create `TreeRing`, a `Timber` `Tree` logger that logs to a
`RingBuffer` instance in orange release builds.

- Create `TreeRingCollector`, called when ACRA reports are generated,
which includes the contents of the ring buffer in the report.

- Enable desugaring to allow the use of java.time libraries on older
Android versions.

- Disable ProGuard obfuscation of class names as the obfuscation adds
additional de-obfuscation steps when handling error reports from users.
2024-02-04 15:17:46 +01:00
Reza Almanda dcf781aa21 fix(l10n): Update Indonesian translations
Currently translated at 45.8% (284 of 619 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/id/
2024-02-03 15:26:43 +01:00
ButterflyOfFire 7cb48a6673 fix(l10n): Update French translations
Currently translated at 97.4% (603 of 619 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/fr/
2024-02-03 15:26:43 +01:00
ButterflyOfFire 409db3019f fix(l10n): Update French translations
Currently translated at 92.7% (574 of 619 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/fr/
2024-02-03 15:26:43 +01:00
bittin1ddc447d824349b2 e5bbb71661 fix(l10n): Update Swedish translations
Currently translated at 100.0% (2 of 2 strings)

Translation: Pachli/App : Google
Translate-URL: https://hosted.weblate.org/projects/pachli/app-google/sv/
2024-02-03 15:26:43 +01:00
bittin1ddc447d824349b2 53ce9d90e6 fix(l10n): Update Swedish translations
Currently translated at 100.0% (2 of 2 strings)

Translation: Pachli/App : Fdroid
Translate-URL: https://hosted.weblate.org/projects/pachli/app-fdroid/sv/
2024-02-03 15:26:43 +01:00
Nik Clayton 1488c13c42
feat: Allow the user to send an error report without a crash (#406)
Getting error reports with logs of strange behaviour is useful even if
the app doesn't crash.

Move crash reporting in to `core.activity`, and provide a menu option
(in orange builds) to trigger a non-fatal crash report that is handled
the same way (i.e., sent by e-mail) as a regular crash report.

`BaseActivity` has to be able to create and handle menus, so adjust
subclasses to call the superclass when necessary.

Update `tools/mvstring` to be able to move strings between different
flavour directories, not just `main`.
2024-02-02 15:34:31 +01:00
Nik Clayton 86d800b1c8
refactor: Modularise "about" activities (#405)
Continue modularisation by moving activities in the "About" feature to a
new `feature.about` module.

Implement `feature.about:
- Move `AboutActivity`, `LicenseActivity`, and `PrivacyPolicyActivity`
here.
- Update `markdown2resource` plugin to work with libraries

Implement `core.data`:
- Types and repositories used through the app
- Move `InstanceInfo` and `InstanceInfoRepository` here so they are
available to `feature.about`.

Implement `core.ui`:
- App-specific views, spans, and other UI content
- Move `ClickableSpanTextView` and `NoUnderlineURLSpan` here so they are
available to `feature.about`.
2024-02-02 15:14:31 +01:00
Nik Clayton 7116c8e0c3
test: Mock searchSync to prevent crash in ComposeActivityTest (#404)
Without the mock the code-under-test was getting a null value where none
should have been possible, and crashing.
2024-02-01 15:50:40 +01:00
ButterflyOfFire ce21b3b9f8 fix(l10n): Update Arabic translations
Currently translated at 94.8% (604 of 637 strings)

Translation: Pachli/App : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/app-main/ar/
2024-01-31 20:19:19 +01:00
Weblate (bot) 1925860731
fix(l10n): Translations update from Hosted Weblate (#397)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for [Pachli/Fastlane
Metadata](https://hosted.weblate.org/projects/pachli/fastlane-metadata/).


It also includes following components:

* [Pachli/App](https://hosted.weblate.org/projects/pachli/ui-strings/)

* [Pachli/Feature -
Login](https://hosted.weblate.org/projects/pachli/feature-login/)

* [Pachli/F-Droid](https://hosted.weblate.org/projects/pachli/f-droid/)

* [Pachli/Core -
Network](https://hosted.weblate.org/projects/pachli/core-network/)

* [Pachli/Core - Design
System](https://hosted.weblate.org/projects/pachli/core-design-system/)

* [Pachli/Core -
Activity](https://hosted.weblate.org/projects/pachli/core-activity/)

* [Pachli/Google](https://hosted.weblate.org/projects/pachli/google/)

* [Pachli/GitHub](https://hosted.weblate.org/projects/pachli/github/)



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/pachli/fastlane-metadata/horizontal-auto.svg)

---------

Co-authored-by: Languages add-on <noreply-addon-languages@weblate.org>
2024-01-30 16:39:45 +01:00
Nik Clayton 358af13dfb
chore: Remove obsolete LicenseCard code (#399)
Unnecessary since the use of `aboutlibraries`
2024-01-30 16:39:19 +01:00
Nik Clayton f0fc0fd530
refactor: Modularise core activity classes, (#393)
Continue modularisation by moving core activity classes that almost all
activities depende on to a `core.activity` module. This includes
core "helper" classes as well.

Implement core.activity:
- Contains BaseActivity, BottomSheetActivity
- Contains LinkHelper and other utility classes used by activities

Implement core.common.extensions:
- Move ViewBindingExtensions and ViewExtensions here

Implement core.common.util:
- Move BlurHashDecoder and VersionName here

Implement core.designsystem:
- Holds common resources (animations, colours, drawables, etc) used
  through the app
- Import "core.designsystem.R as DR" through the app to distinguish
  from the module's own resources

Implement feature.login:
- Move the LoginActivity and related code/resources to its own module

Implement tools/mvstring
- Moves string resources (and all translations) from one module to
  another
2024-01-30 11:37:00 +01:00
Nik Clayton 741bf56f38
chore: Prepare release 2.2.0 (versionCode 11) (#392) 2024-01-29 10:09:57 +01:00
Nik Clayton b454fdceb9
fix: Allow users to retry errors when fetching server info (#391)
Previous code would show errors when fetching server info but with no
mechanism to retry the operation, so it would "stick" until the user
restarted the app.

Fix this with a retry action.

While I'm here use styles to ensure that all snackbars are 5 lines max
length and remove code that sets the length.
2024-01-28 20:13:39 +01:00
Nik Clayton 355244a8e2
refactor: Destructure maps for more idiomatic code (#388) 2024-01-26 12:32:45 +01:00
Nik Clayton fc81e8bad7
fix: Ensure actions happen against the correct status (#373)
Previously when the user interacted with a status the operation (reblog,
favourite, etc) travels through multiple layers of code, carrying with
it the position of the item in the list that the user operated on.

At some point the status is retrieved from the list using its position
so that the correct status ID can be used in the network operation.

If this happens while the list is also refreshing there's a possible
race condition, and the original status' position may have changed in
the list. Looking up the status by position to determine which status to
perform the action on may cause the action to happen on the wrong
status.

Fix this by passing the status' viewdata to any actions instead of its
position. This includes all the information necessary to make the API
call, so there is no chance of a race.

This is quite an involved change because there are three types of
viewdata:

- `StatusViewData`, used for regular timelines
- `NotificationViewData`, used for notifications, may wrap a status that
can be operated on
- `ConversationViewData`, used for conversations, does wrap a status

The previous code treated them all differently, which is probably why it
operated by position instead of type.

The high level fix is to:

1. Create an interface, `IStatusViewData`, that contains the data
exposed by any viewdata that contains a status.

2. Implement the interface in `StatusViewData`, `NotificationViewData`,
and `ConversationViewData`.

3. Change the code that operates on viewdata (`SFragment`,
`StatusActionListener`, etc) to be generic over anything that implements
`IStatusViewData`.

4. Change the code that handles actions to pass the viewdata instead of
the position.

Fixes #370
2024-01-26 12:15:27 +01:00
Nik Clayton c48b8bf545
fix: Don't leak MainActivity in DrawerImageLoader (#382)
Previous code created the drawer image loader as an anonymous inner
class that kept a reference to `glide`, which had a reference to `this`
and could leak.

Fix that by create a separate class that takes these as constructor
parameters.
2024-01-25 17:45:20 +01:00
bittin1ddc447d824349b2 928955e886 fix(l10n): Update Swedish translations
Currently translated at 100.0% (658 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/sv/
2024-01-25 11:28:08 +01:00
bittin1ddc447d824349b2 8dc56be8b6 fix(l10n): Update Swedish translations
Currently translated at 100.0% (658 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/sv/
2024-01-25 11:28:08 +01:00
Reza Almanda 1fc306d890 fix(l10n): Update Indonesian translations
Currently translated at 44.2% (291 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/id/
2024-01-25 11:28:08 +01:00
Anonymous 092a91312a fix(l10n): Update Chinese (Simplified) (zh_MO) translations
Currently translated at 51.5% (339 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/zh_MO/
2024-01-25 11:28:08 +01:00
Anonymous 1e638af89e fix(l10n): Update Chinese (Simplified) translations
Currently translated at 92.0% (606 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/zh_Hans/
2024-01-25 11:28:08 +01:00
Anonymous 28b34aee64 fix(l10n): Update Vietnamese translations
Currently translated at 92.0% (606 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/vi/
2024-01-25 11:28:08 +01:00
Anonymous ec8666edc5 fix(l10n): Update Ukrainian translations
Currently translated at 91.6% (603 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/uk/
2024-01-25 11:28:08 +01:00
Anonymous 0857f3d61d fix(l10n): Update Turkish translations
Currently translated at 91.7% (604 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/tr/
2024-01-25 11:28:08 +01:00
Anonymous 7fb2cd9af1 fix(l10n): Update Thai translations
Currently translated at 66.4% (437 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/th/
2024-01-25 11:28:08 +01:00
Anonymous 6ef6ac15df fix(l10n): Update Slovenian translations
Currently translated at 58.0% (382 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/sl/
2024-01-25 11:28:08 +01:00
Anonymous 92c94ae2b9 fix(l10n): Update Sinhala translations
Currently translated at 36.4% (240 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/si/
2024-01-25 11:28:08 +01:00
Anonymous 9a17096f8d fix(l10n): Update Sanskrit translations
Currently translated at 78.1% (514 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/sa/
2024-01-25 11:28:08 +01:00
Anonymous 11a8429327 fix(l10n): Update Portuguese (Portugal) translations
Currently translated at 78.5% (517 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/pt_PT/
2024-01-25 11:28:08 +01:00
Anonymous b36eba9092 fix(l10n): Update Occitan translations
Currently translated at 91.1% (600 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/oc/
2024-01-25 11:28:08 +01:00
Anonymous b3427f823e fix(l10n): Update Norwegian Bokmål translations
Currently translated at 90.5% (596 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/nb_NO/
2024-01-25 11:28:08 +01:00
Anonymous 73c80825f1 fix(l10n): Update Latvian translations
Currently translated at 83.2% (548 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/lv/
2024-01-25 11:28:08 +01:00
Anonymous 3829e8bd31 fix(l10n): Update Korean translations
Currently translated at 57.2% (377 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/ko/
2024-01-25 11:28:08 +01:00
Anonymous 9a68df58f6 fix(l10n): Update Kabyle translations
Currently translated at 37.3% (246 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/kab/
2024-01-25 11:28:08 +01:00
Anonymous 978f1fccee fix(l10n): Update Icelandic translations
Currently translated at 90.5% (596 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/is/
2024-01-25 11:28:08 +01:00
Anonymous 612043d3fe fix(l10n): Update Hungarian translations
Currently translated at 90.5% (596 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/hu/
2024-01-25 11:28:08 +01:00
Anonymous 4d8e8fa020 fix(l10n): Update Hindi translations
Currently translated at 55.9% (368 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/hi/
2024-01-25 11:28:08 +01:00
Anonymous 9e1b6f9d02 fix(l10n): Update Galician translations
Currently translated at 91.9% (605 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/gl/
2024-01-25 11:28:08 +01:00
Anonymous c1c99db75b fix(l10n): Update Gaelic translations
Currently translated at 91.6% (603 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/gd/
2024-01-25 11:28:08 +01:00
Anonymous 79648170d1 fix(l10n): Update Irish translations
Currently translated at 64.5% (425 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/ga/
2024-01-25 11:28:08 +01:00
Anonymous 53c1485dbf fix(l10n): Update French translations
Currently translated at 89.3% (588 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/fr/
2024-01-25 11:28:08 +01:00
Anonymous ab7003efc4 fix(l10n): Update Persian translations
Currently translated at 92.0% (606 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/fa/
2024-01-25 11:28:08 +01:00
Anonymous 9ddb965d6b fix(l10n): Update Basque translations
Currently translated at 71.5% (471 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/eu/
2024-01-25 11:28:08 +01:00
Anonymous 4b4a736db0 fix(l10n): Update Esperanto translations
Currently translated at 74.0% (487 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/eo/
2024-01-25 11:28:08 +01:00
Anonymous 181b8198be fix(l10n): Update German translations
Currently translated at 97.7% (643 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/de/
2024-01-25 11:28:08 +01:00
Anonymous 2fd6f96706 fix(l10n): Update Welsh translations
Currently translated at 92.0% (606 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/cy/
2024-01-25 11:28:08 +01:00
Anonymous b36cf1dbc0 fix(l10n): Update Czech translations
Currently translated at 74.9% (493 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/cs/
2024-01-25 11:28:08 +01:00
Anonymous 2979959e87 fix(l10n): Update Kurdish (Central) translations
Currently translated at 63.3% (417 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/ckb/
2024-01-25 11:28:08 +01:00
Anonymous d0e77b4a5c fix(l10n): Update Catalan translations
Currently translated at 84.8% (558 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/ca/
2024-01-25 11:28:08 +01:00
Anonymous cc5a535730 fix(l10n): Update Bengali (India) translations
Currently translated at 62.4% (411 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/bn_IN/
2024-01-25 11:28:08 +01:00
Anonymous 8919650cc7 fix(l10n): Update Bengali (Bangladesh) translations
Currently translated at 66.7% (439 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/bn_BD/
2024-01-25 11:28:08 +01:00
Anonymous 50f4df1693 fix(l10n): Update Belarusian translations
Currently translated at 88.1% (580 of 658 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/be/
2024-01-25 11:28:08 +01:00
Reza Almanda d501d7d35d fix(l10n): Update Indonesian translations
Currently translated at 42.6% (277 of 650 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/id/
2024-01-25 11:28:08 +01:00
Reza Almanda 1e13a040b4 fix(l10n): Update Indonesian translations
Currently translated at 40.3% (262 of 650 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/id/
2024-01-25 11:28:08 +01:00
Nik Clayton dcc2954148
fix: Show correct trending tag values at the end of the chart lines (#380)
The previous code incorrectly showed the trending tag usage data twice
next to the end of the trending tag lines, instead of one entry for the
usage data and one entry for the account data.

Fix that.

As part of this fix change how the data is displayed. Instead of using
two distinct `TextView`, fixed to the bottom end of the chart, draw the
text directly on the chart. The text is accurately position so that it
is next to the end of the relevant line. If both lines overlap the label
positions are adjusted appropriately.

The chart now uses Pachli blue and orange for the line colours.

While doing this I discovered that the mechanism used to fall back to
particular chart colours if none were specified was incorrect, so fix
that too.
2024-01-25 00:50:50 +01:00
Nik Clayton bdb3a61523
feat: Disable tag mute feature if server can't filter (#378)
If the server doesn't support filtering then it's impossible to mute a
hashtag (which works by creating a filter). In this case hide the UI.
2024-01-23 23:29:10 +01:00
Nik Clayton 88066302ab
build: Disable lint warnings about old versions of AGP (#379)
They're caught via GH Actions, and block builds unnecessarily.
2024-01-23 23:18:27 +01:00
Nik Clayton 5cfe6d055b
fix: Improve parsing of Friendica (and other server) version formats (#376)
Previous code could return an error on Friendica version strings like
`2024.03-dev-1547`.

Fix this:

- Extend the list of explicitly supported servers to include Fedibird,
Friendica, Glitch, Hometown, Iceshrimp, Pixelfed, and Sharkey.

- Add version parsing routines for these servers.

- Test the version parsing routines fetching every server and version
seen by Fediverse Observer (~ 2,000 servers) and ensuring that the
server and version information can be parsed.

Improve the error message:

- Show the hostname with a `ServerRepository` error

Clean up the code:

- Remove the custom `resultOf` and `mapResult` functions, they have
equivalents in newer versions of the library (like `runSuspendCatching`)

Fixes #372
2024-01-23 20:27:25 +01:00
Nik Clayton 7e3cde4c65
refactor: Remove unused logging tags (#374) 2024-01-23 16:59:56 +01:00
Nik Clayton a588c702fb
fix: Prevent crash by keeping network.model.** classes (#369)
Previous rule didn't consider a deeper package hierarchy, so the new
NodeInfo classes were being removed by ProGuard.
2024-01-19 09:39:44 +01:00
Martijn de Boer 875bb9c2a5 fix(l10n): Update Dutch translations
Currently translated at 100.0% (650 of 650 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/nl/
2024-01-18 22:02:47 +01:00
Jener Gomes ee0fdf86b3 fix(l10n): Update Portuguese (Brazil) translations
Currently translated at 100.0% (650 of 650 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/pt_BR/
2024-01-18 22:02:47 +01:00
Kalle Kniivilä 1bbe32d6c0 fix(l10n): Update Finnish translations
Currently translated at 100.0% (650 of 650 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/fi/
2024-01-18 22:02:47 +01:00
Kalle Kniivilä 37a6826df7 fix(l10n): Update Finnish translations
Currently translated at 86.6% (563 of 650 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/fi/
2024-01-18 22:02:47 +01:00
Martijn de Boer c50bbf86ca fix(l10n): Update Dutch translations
Currently translated at 99.6% (648 of 650 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/nl/
2024-01-18 22:02:47 +01:00
ButterflyOfFire 970a7574a7 fix(l10n): Update Arabic translations
Currently translated at 94.6% (615 of 650 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/ar/
2024-01-18 22:02:47 +01:00
Nik Clayton 42219875e9
fix: Disable filter functionality if unsupported by the server (#366)
The previous code unilaterally enabled filter functionality. Some
Mastodon-like servers -- like GoToSocial -- do not support filters, and
this resulted in user visible error messages when connecting to those
servers.

To fix this:

- Extend the set of supported server capabilities to include client and
server side filtering.

- Disable the filter preferences if the server does not support filters
and show a message explaining why it's disabled.

Extend the capabilities model to support this:

- Fetch server software name and version from the nodeinfo endpoints
(implementing the nodeinfo API and schema)

- Extend the use of kotlin-result to provide hierarchies of Error
classes and demonstrate how to chain errors and display more informative
messages without using exceptions.

Fixes #343
2024-01-18 21:44:30 +01:00
Nik Clayton aaf8cf57f3
refactor: Provide TestScope as ApplicationScope in tests (#364)
Previously some tests had to manually create dependencies (instead of
injecting them) because the dependency required the `TestScope`
`CoroutineScope` as one of its dependencies.

Resolve this with a `FakeCoroutineScopeModule` that provides `TestScope`
as `@ApplicationScope`. The tests can now inject their dependencies,
which will use `TestScope`.

To inject `AccountPreferenceDataStore` it has been updated to use the
current active account when reading or writing preferences.
2024-01-17 16:41:41 +01:00
Nik Clayton 993b74691a
chore(deps): update plugin ktlint to v12.1.0 (#358) 2024-01-09 17:50:20 +01:00
Nik Clayton d8be70a465
chore(deps): update plugin ktlint to v12 (#357) 2024-01-08 23:26:46 +01:00
Nik Clayton 51c2ef0607
chore: Prepare release 2.1.1 (versionCode 10) (#331) 2023-12-17 07:15:46 +01:00
Nik Clayton 88466373b3
chore: Prepare release 2.1.0 (versionCode 9) (#327) 2023-12-15 15:50:20 +01:00
bittin1ddc447d824349b2 49a31dd80b fix(l10n): Update Swedish translations
Currently translated at 100.0% (650 of 650 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/sv/
2023-12-15 11:38:09 +01:00
Kalle Kniivilä 4db3b35023 fix(l10n): Update Finnish translations
Currently translated at 72.3% (470 of 650 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/fi/
2023-12-15 11:38:09 +01:00
Nik Clayton b294a3bace
fix: Correctly show if an account is a bot or not (#322)
e35fa1db inadvertently contained some left over debug code that treats
non-bot accounts as bots (for displaying the bot badge) and vice versa.

Fixes #321
2023-12-14 11:27:49 +01:00
Nik Clayton 29f9273c01
fix: Show translated content when viewing a thread (#320)
If a status was part of a thread, and it was not the "detailed" status,
and it had been translated, then the view data was marked as "show the
translation". But the translation was not loaded, so the status content
appeared as empty.

Fix that by loading the translated content of all statuses in the thead
and ensure that the translated content is rendered.

Throw an `IllegalStateException` in debug builds to catch any future
occurrences of this.

Fixes #281
2023-12-13 17:18:07 +01:00
Nik Clayton bf36837b04
feat: Allow the user to report crashes in orange builds (#317)
Add a dependency on ACRA (in orange builds only), and catch crashes.

The user is given the option to e-mail the crash report data to the
support address, and can view and edit/redact the data before doing so.
2023-12-12 23:25:09 +01:00
Nik Clayton 098983f401
fix: Calculate length of posts and polls with emojis correctly (#315)
Mastodon counts post lengths by considering emojis to be single
characters, no matter how many unicode code points they are composed of.
So "😜" has length 1.

Pachli was using `String.length`, which considers "😜" as length 2.

Correct the calculation by using a BreakIterator to count the characters
in the string, which treats multi-character emojis as a length 1.

Poll options had a similar problem, exacerbated by the Mastodon web UI
also having the same problem, see
https://github.com/mastodon/mastodon/issues/28336.

Fix that by creating `MastodonLengthFilter`, an `InputFilter` that does
the right thing for regular text that may contain emojis.

See also https://github.com/tuskyapp/Tusky/pull/4152, which has the fix
for status length but not polls.

---------

Co-authored-by: Konrad Pozniak <opensource@connyduck.at>
2023-12-12 16:53:09 +01:00
Kalle Kniivilä 07e1d4c760 fix(l10n): Update Finnish translations
Currently translated at 60.2% (390 of 647 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/fi/
2023-12-12 14:09:35 +01:00
Nik Clayton cbecfa3117
feat: Show roles on profiles (#312)
Roles for the logged in user appeared in Mastodon 4.0.0 and can be
displayed on the user's profile screen.

Show them as chips, adjusting the display of the existing "Follows you"
and "Bot" indicators to make allowances for this.

Roles can have a custom colour assigned by the server admin. This is
blended with the app colour so it is not too jarring in the display.

See also https://github.com/tuskyapp/Tusky/pull/4029

Co-authored-by: Konrad Pozniak <opensource@connyduck.at>
2023-12-11 20:57:11 +01:00
Nik Clayton 60cfa99f17
refactor: Use AppTheme enum exclusively (#311)
Previous code treated the app theme as a mix of strings and enums.
Convert to exclusively use the `AppTheme` enum to improve type safety.
2023-12-11 14:41:36 +01:00
Nik Clayton 2a7eda667b fix: Prevent crash if a preview card does not have an author 2023-12-09 22:49:21 +01:00
Nik Clayton 4f65321a9d fix: Prevent crash if an error is shown in a timeline without a FAB 2023-12-09 22:49:21 +01:00
Nik Clayton df45c0cd96 fix: Prevent crash showing profile if account has null `createdAt` field 2023-12-09 22:49:21 +01:00
Nik Clayton d4eed2fbf8
fix: Prevent memory leak in CompositeWithOpaqueBackground (#309)
Quoting @connyduck in https://github.com/tuskyapp/Tusky/pull/4150:

"""
The transformation ends up in Glide's memory cache and leaks whole
Activities through the view -> context reference.

This fixes the problem by removing the background detection logic (so
the view reference is no longer needed) and setting the background
directly instead. Looks exactly as before.
"""

Co-authored-by: Konrad Pozniak <opensource@connyduck.at>
2023-12-09 18:36:49 +01:00
Nik Clayton 6ee41177cd
build: Install LeakCanary in debug builds (#308) 2023-12-09 18:06:01 +01:00
Kalle Kniivilä 0251801d7e fix(l10n): Update Finnish translations
Currently translated at 60.1% (389 of 647 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/fi/
2023-12-09 17:49:16 +01:00
Nik Clayton 1214cf7c8a
refactor: Break navigation dependency cycles with :core:navigation (#305)
The previous code generally started an activity by having the activity
provide a method in a companion object that returns the relevant intent,
possibly taking additional parameters that will be included in the
intent as extras.

E.g., if A wants to start B, B provides the method that returns the
intent that starts B.

This introduces a dependency between A and B.

This is worse if B also wants to start A.

For example, if A is `StatusListActivity` and B is`ViewThreadActivity`.
The user might click a status in `StatusListActivity` to view the
thread, starting `ViewThreadActivity`. But from the thread they might
click a hashtag to view the list of statuses with that hashtag. Now
`StatusListActivity` and `ViewThreadActivity` have a circular
dependency.

Even if that doesn't happen the dependency means that any changes to B
will trigger a rebuild of A, even if the changes to B are not relevant.

Break this dependency by adding a `:core:navigation` module with an
`app.pachli.core.navigation` package that contains `Intent` subclasses
that should be used instead. The `quadrant` plugin is used to generate
constants that can be used to launch activities by name instead of by
class, breaking the dependency chain.

The plugin uses the `Activity` names from the manifest, so when an
activity is moved in the future the constant will automatically update
to reflect the new package name.

If the activity's intent requires specific extras those are passed via
the constructor, with companion object methods to extract them from the
intent.

Using the intent classes from this package is enforced by a lint
`IntentDetector` which will warn if any intents are created using a
class literal.

See #291
2023-12-07 18:36:00 +01:00
Nik Clayton 2ce80c6a32
refactor: Use the correct package for TimelineKind (#303)
The package wasn't renamed when it was moved, so was still
`app.pachli.components.timeline`, instead of the new location,
`app.pachli.core.network.model`.
2023-12-06 12:20:36 +01:00
Nik Clayton e749b362ca
refactor: Start creating core modules (#286)
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.
2023-12-04 16:58:36 +01:00
sanao a7533b3f08
feat: Display compose button when viewing lists (#279)
Fixes #231
2023-12-04 16:42:32 +01:00
sanao fbbb6249cc
feat: Display compose button when viewing bookmarks list (#278)
Fixes #230
2023-12-04 16:29:14 +01:00
renovate[bot] 02b17f4144
fix(deps): update dependency com.android.tools.build:gradle to v8.2.0 (#257)
[![Mend Renovate logo
banner](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
|
[com.android.tools.build:gradle](https://developer.android.com/studio/build)
([source](https://android.googlesource.com/platform/tools/base)) |
`8.1.2` -> `8.2.0` |
[![age](https://developer.mend.io/api/mc/badges/age/maven/com.android.tools.build:gradle/8.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.android.tools.build:gradle/8.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.android.tools.build:gradle/8.1.2/8.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.android.tools.build:gradle/8.1.2/8.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [com.android.tools.lint:lint-tests](http://tools.android.com/) |
`31.1.3` -> `31.2.0` |
[![age](https://developer.mend.io/api/mc/badges/age/maven/com.android.tools.lint:lint-tests/31.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.android.tools.lint:lint-tests/31.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.android.tools.lint:lint-tests/31.1.3/31.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.android.tools.lint:lint-tests/31.1.3/31.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [com.android.tools.lint:lint](http://tools.android.com/) | `31.1.3` ->
`31.2.0` |
[![age](https://developer.mend.io/api/mc/badges/age/maven/com.android.tools.lint:lint/31.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.android.tools.lint:lint/31.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.android.tools.lint:lint/31.1.3/31.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.android.tools.lint:lint/31.1.3/31.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [com.android.tools.lint:lint-checks](http://tools.android.com/) |
`31.1.3` -> `31.2.0` |
[![age](https://developer.mend.io/api/mc/badges/age/maven/com.android.tools.lint:lint-checks/31.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.android.tools.lint:lint-checks/31.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.android.tools.lint:lint-checks/31.1.3/31.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.android.tools.lint:lint-checks/31.1.3/31.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [com.android.tools.lint:lint-api](http://tools.android.com/) |
`31.1.3` -> `31.2.0` |
[![age](https://developer.mend.io/api/mc/badges/age/maven/com.android.tools.lint:lint-api/31.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.android.tools.lint:lint-api/31.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.android.tools.lint:lint-api/31.1.3/31.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.android.tools.lint:lint-api/31.1.3/31.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/pachli/pachli-android).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy41OS44IiwidXBkYXRlZEluVmVyIjoiMzcuNTkuOCIsInRhcmdldEJyYW5jaCI6Im1haW4ifQ==-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Nik Clayton <nik@ngo.org.uk>
2023-12-02 14:34:34 +01:00
Nik Clayton f9fb0e87b4
fix: Prevent UnsupportedOperationException in PachliTileService (#288)
Previous code always called `startActivityAndCollapse()` with a regular
intent, which triggers an `UnsupportedOperationException` at API 34.

Use the non-deprecated variant that uses pending intents when
appropriate.

While looking at this I noticed the icon for the tile was incorrect, so
replaced that with the notification icon.
2023-12-02 14:24:29 +01:00
Jener Gomes d2ef0b0713 fix(l10n): Update English (United Kingdom) translations
Currently translated at 12.3% (80 of 647 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/en_GB/
2023-12-01 17:00:58 +01:00
sköldpadda 96d6c3bed3 fix(l10n): Update Swedish translations
Currently translated at 99.8% (646 of 647 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/sv/
2023-12-01 17:00:58 +01:00
Jener Gomes abc7a180bf fix(l10n): Update Portuguese (Brazil) translations
Currently translated at 100.0% (647 of 647 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/pt_BR/
2023-12-01 17:00:58 +01:00
Jener Gomes ad8d689165 fix(l10n): Update Spanish translations
Currently translated at 100.0% (647 of 647 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/es/
2023-12-01 17:00:58 +01:00
Jener Gomes ef6db89665 fix(l10n): Update English translations
Currently translated at 100.0% (647 of 647 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/en/
2023-12-01 17:00:58 +01:00
Jener Gomes a097b09af6 fix(l10n): Update Portuguese (Brazil) translations
Currently translated at 99.8% (646 of 647 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/pt_BR/
2023-12-01 17:00:58 +01:00
sanao bfdd8c943f fix(l10n): Update Japanese translations
Currently translated at 100.0% (647 of 647 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/ja/
2023-12-01 17:00:58 +01:00
Nik Clayton 3827c09165
chore: Prepare release 2.0.0 (versionCode 8) (#277) 2023-11-23 12:53:58 +01:00
sanao 06f2fa27e2
feat: Display compose button when viewing favorites list (#276)
Display the "compose" FAB when viewing the favourite list. 

Fixes #229
2023-11-23 11:32:08 +01:00
Nik Clayton 4992aa9c52
feat: Increase the amount of information in link previews (#275)
Show up to two lines of the link's title and three lines of the link's
description in link preview cards. This provides additional useful
context to the user, especially when many links bury the important
information at the end of the title.
2023-11-21 20:06:29 +01:00
Nik Clayton 123c251fc9
feat: Warn the user about an Android animation bug (#274)
Upgrading to this version of Pachli may trigger an Android bug where
cached animation specifications are not cleared, resulting in incorrect
animations (e.g., when navigating between activities).

This is an Android bug triggered by the Android Material library,
https://github.com/material-components/material-components-android/issues/3644.

Show the user a dialog (once) when launching after an upgrade, so they
know to restart their device if necessary.
2023-11-21 16:05:42 +01:00
Nik Clayton 806991f8a8
fix: Prevent a ClassCastException when handling timeline errors (#273) 2023-11-21 13:48:41 +01:00
Nik Clayton a6a68f1384
fix: Use transparent system bar on all Android versions (#272)
Previous code use transparent system bars on v29, resulting in the wrong
colours in preferences and other activities on some devices.

Fixes #267
2023-11-21 00:02:52 +01:00
vinz e72431d15c fix(l10n): Update German translations
Currently translated at 99.6% (643 of 645 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/de/
2023-11-20 21:41:23 +01:00
renovate[bot] 8043f9fe1c
fix(deps): update material.drawer to v9 (major) (#127)
[![Mend Renovate logo
banner](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
|
[com.mikepenz:materialdrawer-iconics](https://togithub.com/mikepenz/MaterialDrawer)
| `8.4.5` -> `9.0.2` |
[![age](https://developer.mend.io/api/mc/badges/age/maven/com.mikepenz:materialdrawer-iconics/9.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.mikepenz:materialdrawer-iconics/9.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.mikepenz:materialdrawer-iconics/8.4.5/9.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.mikepenz:materialdrawer-iconics/8.4.5/9.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
|
[com.mikepenz:materialdrawer](https://togithub.com/mikepenz/MaterialDrawer)
| `8.4.5` -> `9.0.2` |
[![age](https://developer.mend.io/api/mc/badges/age/maven/com.mikepenz:materialdrawer/9.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.mikepenz:materialdrawer/9.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.mikepenz:materialdrawer/8.4.5/9.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.mikepenz:materialdrawer/8.4.5/9.0.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>mikepenz/MaterialDrawer
(com.mikepenz:materialdrawer-iconics)</summary>

###
[`v9.0.2`](https://togithub.com/mikepenz/MaterialDrawer/releases/tag/v9.0.2)

##### 🚀 Features

-   Update to Gradle 7.5.1
- PR:
[#&#8203;2788](https://togithub.com/mikepenz/MaterialDrawer/issues/2788)
-   Bump git from 1.11.0 to 1.13.0
- PR:
[#&#8203;2792](https://togithub.com/mikepenz/MaterialDrawer/issues/2792)
-   Upgrade all dependencies to the latest version
- PR:
[#&#8203;2798](https://togithub.com/mikepenz/MaterialDrawer/issues/2798)

##### 🐛 Fixes

-   fix getColorStateList for API22 and below
- PR:
[#&#8203;2797](https://togithub.com/mikepenz/MaterialDrawer/issues/2797)
    -   Thanks [@&#8203;bmx666](https://togithub.com/bmx666)

##### 💬 Other

-   Dependency Submission API
- PR:
[#&#8203;2782](https://togithub.com/mikepenz/MaterialDrawer/issues/2782)
-   Update CI pipeline for dependency submission API
- PR:
[#&#8203;2783](https://togithub.com/mikepenz/MaterialDrawer/issues/2783)
-   Run dependency submission action on dev branch
- PR:
[#&#8203;2784](https://togithub.com/mikepenz/MaterialDrawer/issues/2784)
-   Update Dependency submission for all modules
- PR:
[#&#8203;2787](https://togithub.com/mikepenz/MaterialDrawer/issues/2787)

###
[`v9.0.1`](https://togithub.com/mikepenz/MaterialDrawer/releases/tag/v9.0.1)

##### 🚀 Features

-   Upgrade dependencies 2022.06.24
- PR:
[#&#8203;2780](https://togithub.com/mikepenz/MaterialDrawer/issues/2780)

##### 🐛 Fixes

-   Enhance selected color selection MiniDrawerItem
- PR:
[#&#8203;2779](https://togithub.com/mikepenz/MaterialDrawer/issues/2779)
    -   Thanks [@&#8203;hamedgramzi](https://togithub.com/hamedgramzi)

###
[`v9.0.0`](https://togithub.com/mikepenz/MaterialDrawer/releases/tag/v9.0.0)

##### 🚀 Features

-   Material 3 theme
- PR:
[#&#8203;2756](https://togithub.com/mikepenz/MaterialDrawer/issues/2756)
- PR:
[#&#8203;2757](https://togithub.com/mikepenz/MaterialDrawer/issues/2757)
-   Upgrade environment | Kotlin 1.6 | Material 1.5.0-beta01
- PR:
[#&#8203;2758](https://togithub.com/mikepenz/MaterialDrawer/issues/2758)
-   Kotlin 1.6.10 | Material Components 1.5.0
- PR:
[#&#8203;2762](https://togithub.com/mikepenz/MaterialDrawer/issues/2762)
-   Upgrade to Navigation 2.4.x
- PR:
[#&#8203;2770](https://togithub.com/mikepenz/MaterialDrawer/issues/2770)
-   Upgrade dependencies | Kotlin 1.6.20
- PR:
[#&#8203;2774](https://togithub.com/mikepenz/MaterialDrawer/issues/2774)
-   Add successListener to setupWithNavController()
- PR:
[#&#8203;2773](https://togithub.com/mikepenz/MaterialDrawer/issues/2773)
- Thanks [@&#8203;shmueldabomb441](https://togithub.com/shmueldabomb441)

##### 🐛 Fixes

-   Do not set `selectOnLongClick` on `multiSelect=false`
- PR:
[#&#8203;2771](https://togithub.com/mikepenz/MaterialDrawer/issues/2771)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these
updates again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/pachli/pachli-android).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4xMDcuMiIsInVwZGF0ZWRJblZlciI6IjM3LjU5LjgiLCJ0YXJnZXRCcmFuY2giOiJtYWluIn0=-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Nik Clayton <nik@ngo.org.uk>
2023-11-20 20:37:56 +01:00
sanao adb9fcf468
feat: Display compose button when viewing hashtags (#254)
Display the "compose" FAB when viewing a hashtag list. Tapping the
button will open `ComposeActivity` prepopulated with the hashtag at the
end of the post with the cursor at the start.

Fixes #228
2023-11-20 19:19:51 +01:00
vinz 1f21bd45d4 fix(l10n): Update German translations
Currently translated at 98.9% (638 of 645 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/de/
2023-11-19 16:28:52 +01:00
sanao e97ce6f303 fix(l10n): Update Japanese translations
Currently translated at 100.0% (645 of 645 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/ja/
2023-11-17 14:09:04 +01:00
sanao 432e262e32 fix(l10n): Update Japanese translations
Currently translated at 100.0% (645 of 645 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/ja/
2023-11-17 14:09:04 +01:00
Nik Clayton 46d81b3c68
fix: Ensure update-related data classes are retained (#269)
Prevents a crash if Proguard optimises them away in release builds.
2023-11-17 12:27:28 +01:00
Nik Clayton 34c88b0291
fix: Prevent colour related crash on API level ~ 26 (#262)
Viewing edited statuses could crash on API levels around 26 with a
ResourceNotFoundException. Using `?colorOutline` for the divider colour
instead of `?android:textColorPrimary` fixes this, and is also a better
colour to use.
2023-11-16 11:44:09 +01:00
Nik Clayton fce34cced1
fix: Update themes to correct poll/black theme issues (#255)
`Theme.Pachli` was being overriden on v29+ devices which meant that poll
options were showing with too much padding. Fix that by using `AppTheme`
as the final theme, and basing that off `Theme.Pachli`.

Black themes were using dark grey for toolbar and tab backgrounds, so
fix that too for a seamless experience with the black theme.
2023-11-15 15:59:01 +01:00
Nik Clayton 09dc830c86
fix: Collect the server capabilities in SFragment subclasses (#252)
Not all subclasses were calling `super.onViewCreated()` so collecting
the server capability wasn't happening consistently. Fix this, and add a
`@CallSuper` annotation to prevent the problem from recurring.
2023-11-13 16:44:29 +01:00
Nik Clayton 1c6c8a7455
fix: Keep network model classes, preventing crash on startup (#251)
Without this the model classes are not retained, which causes a
`ClassCastException` when parsing the new models for the instance v1 and
instance v2 API calls.

Fixes #250
2023-11-13 13:31:31 +01:00
Nik Clayton d40b87f0a0
feat: Translate statuses on cached timelines (#220)
Implement some support for server-side status translation. Do this by:

- Implement support for the `api/v1/instance` endpoint to determine if
  the remote server supports translation.

- Create new `ServerCapabilities` to allow the app to query the remote
  capabilities in a server-agnostic way. Use this to query if the
  remote server supports the Mastodon implementation of server-side
  translation

- If translation is supported then show a translate/undo translate
  option on the status "..." menu.

- Fetch translated content from the server if requested, and store it
  locally as a new Room entity.

- Update displaying a status to check if the translated version
  should be displayed; if it should then new code is used to show
  translated content, content warning, poll options, and media
  descriptions.

- Add a `TextView` to show an "in progress" message while translation
  is happening, and to show the translation provider (generally
  required by agreements with them).

Partially fixes #62

---------

Co-authored-by: sanao <naosak1006@gmail.com>
2023-11-12 19:51:46 +01:00
chaoscalm 27367d94bd fix(l10n): Update Italian translations
Currently translated at 97.6% (625 of 640 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/it/
2023-11-12 12:44:03 +01:00
Nik Clayton 9b85ae08a1
chore: Prepare release 1.4.0 (versionCode 7) (#241) 2023-11-10 13:55:32 +01:00
Nik Clayton 0816071eea
fix(l10n): Update Italian translations (#240)
Based on work originally carried out by chaoscalm in
https://github.com/pachli/pachli-android/pull/206.
2023-11-10 12:52:52 +01:00
Nik Clayton 380bc6fa1e
fix: Ensure navigation and status bar icons are visible (#239) 2023-11-09 19:12:41 +01:00
Nik Clayton e03825cc12
ci: Use correct versionCode for orange.* versions (#237)
Now that the flavour includes the store name it's not sufficient to
check for "orange" as the flavour, as that no longer matches. Now it
must start with "orange" to trigger using the git commit count as the
version code.
2023-11-08 09:59:13 +01:00
Nik Clayton dda9dde1b9
feat: Periodically check for updates and alert user (#236)
Users can inadvertently get stuck on older versions of the app; e.g., by
installing from one F-Droid repository that stops hosting the app at
some later time.

Analytics from the Play Store also shows a long tail of users who are,
for some reason, on an older version.

On resuming `MainActivity`, and approximately once per day, check and
see if a newer version of Pachli is available, and prompt the user to
update by going to the relevant install location (Google Play, F-Droid,
or GitHub).

The dialog prompt allows them to ignore this specific version, or
disable all future update notifications. This is also exposed through
the preferences, so the user can adjust it there too.

A different update check method is used for each installation location.

- F-Droid: Use the F-Droid API to query for the newest released version
- GitHub: Use the GitHub API to query for the newest release, and check
the APK filename attached to that release
- Google Play: Use the Play in-app-updates library
(https://developer.android.com/guide/playcore/in-app-updates) to query
for the newest released version

These are kept in different build flavours (source sets), so that e.g.,
the build for the F-Droid store can only query the F-Droid API, the UI
strings are specific to F-Droid, etc. This also ensures that the update
service libraries are specific to that build and do not
"cross-contaminate".

Note that this *does not* update the app, it takes the user to either
the relevant store page (F-Droid, Play) or GitHub release page. The user
must still start the update from that page.

CI configuration is updated to build the different flavours.
2023-11-08 08:42:39 +01:00
Nik Clayton 86dee94035
refactor: Convert Java to Kotlin (#235) 2023-11-06 20:16:34 +01:00
Nik Clayton cc2974cb69
fix: Show preference changes immediately (#234)
The preference change listener was being optimised out by R8, causing
rapid garbage collection, breaking the `changes` flow in release builds.

Fix this by annotating the field with `@Keep` so it is retained.

Fixes #225
2023-11-06 19:02:13 +01:00
Nik Clayton 392eb55485
fix: Honour the FAB_HIDE preference in timelines (#227) 2023-11-06 16:29:46 +01:00
Nik Clayton bd452b53a5
fix: Ensure system controls are visible on older devices (#224)
Previous code always set `navigationBarColor` and `statusBarColor` to
`transparent` irrespective of the API level.

This only works on API 29 and above; if you do it on API levels lower
than that the system navigation buttons (home, back, recents) are
typically shown on a very similar colour to the background, making them
very hard to see.

Fixes #221
2023-11-05 22:19:39 +01:00
Nik Clayton c350d17646
refactor: Remove additional unused code after migrating to Timber (#219) 2023-11-05 14:50:23 +01:00
sanao 4b7eb2419e
refactor: Use com.google.android.material.appbar.MaterialToolbar
The previous code used `androidx.appcompat.widget.Toolbar` in a several
places.

It's better to use `MaterialToolbar` as that plays better with other
Material components.

Update the usage throughout the project.

In addition, implement a lint check that will prevent any future use
from creeping back in.

Fixes #28
2023-11-05 13:51:37 +01:00
Nik Clayton f8877909ca
refactor: Log with Timber (#218)
Use Timber instead of `android.util.Log`. Removes the need for `TAG`
statics in companion objects, slightly simplifying the code. Opens the
door for some production logging in the future.
2023-11-04 22:22:44 +01:00
Nik Clayton 6aa4eab75d
fix: Remove progressbar from status timelines (#208)
Previously the middle-of-screen progress spinner and the spinner that
appears on a swipe-to-refresh could get out of sync.

Fix this by removing the middle-of-screen progress spinner from relevant
fragments, as the swipe-to-refresh spinner shows the user that an
operation is in progress, and also clues them in to the fact that a
swipe-to-refresh is possible (by using the common UX control).

Fixes #75
2023-10-30 19:26:40 +01:00
Nik Clayton c3f68ba9b8
fix: Refer to "SDK level" rather than "SDK version" (#211)
"level" is the term used throughout Android documentation.

Originally submitted by https://github.com/chaoscalm
2023-10-30 19:25:53 +01:00
Nik Clayton e5a54061aa
build: Use `updateLintBaseline` task (#209)
There's a well-hidden `updateLintBaseline` task that does what the
custom `newLintBaseline` task does. Prefer the `update...` task to
reduce the amount of custom machinery in this build.
2023-10-30 19:03:45 +01:00
Nik Clayton 9dad367f6f
fix: Restore image aspect ratio when drag ends (#207)
Previously, ending a drag on an image (that didn't result in dismissing
the fragment) animates the image back in to position restoring the X
axis scale factor.

The Y axis scale factor was not restored, potentially breaking the
image's aspect ratio. Restore the Y axis scale factor to fix this
(`ViewVideoFragment` already handles this correctly).

Fixes #202
2023-10-28 20:28:57 +02:00
Nik Clayton 523efa705c
fix: Prevent potential crash when filters are slow to load (#205)
This previous code could crash if `filterModel.kind` (marked `lateinit`)
had not been set before the filters are loaded. This could happen in
rare cases.

Fix this by rewriting `FilterModel`. Instead of creating a half-empty
object that still needs further initialisation, delay the creation until
all the necessary information is available, and pass it in the
`FilterModel` constructor.

This also forces code that uses `FilterModel` to properly handle the
case where it might be null at the point where filtering decisions have
to be made.

This means that `TimelineViewModel` (and subclasses) no longer need the
`init()` function to complete their construction, which was another
significant code smell. Pass the `TimelineKind` to the view models via
their `SavedStateHandle`.

This showed that changing filters wasn't causing the timelines to update
without a manual refresh, so fix that too. Editing filters sends change
events for the old and new contexts (in case a context is removed from a
filter), and deleting a filter sends a change event too.
2023-10-28 19:54:46 +02:00
chaoscalm 34e37f9ebb
fix(l10n): Update Italian translations (#204) 2023-10-28 13:43:41 +02:00
Nik Clayton 3705a29dd0
fix: Use the correct name for filters affecting threads (#203)
Previous code called filters that affect threads "Conversations".
Correct this to "Threads", to distinguish from "Direct Messages" which
can also be known as "conversations" (in the API in particular).
2023-10-26 23:34:04 +02:00
Nik Clayton ca8c1d9181
chore: Update copyright notice to refer to Pachli for the license (#201)
Previous copyright notice mentioned that the license should have been
distributed with Tusky. Correct that to Pachli.

This does not change the copyright assignment, only the instructions
as to where to find the license.
2023-10-26 16:41:12 +02:00
Nik Clayton 2f3851acee
refactor: Convert Java viewholders to Kotlin (#200) 2023-10-26 16:22:18 +02:00
Nik Clayton 0598c0e667
chore: Remove unused DAO functions (#199) 2023-10-26 12:23:10 +02:00
Nik Clayton 6b12ecfd7a
fix(deps): update androidx.room to v2.6.0 (#198)
Enable Kotlin code generation, and use the new room plugin to generate
schemas in a reproducible/cacheable way.
2023-10-25 18:39:31 +02:00
Nik Clayton 9c4ea13d23
chore: Prepare release 1.3.0 (versionCode 6) (#197) 2023-10-25 09:52:25 +02:00
sanao 00bde27eb3 fix(l10n): Update Japanese translations
Currently translated at 100.0% (632 of 632 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/ja/
2023-10-25 09:05:27 +02:00
sanao 1f2f4d51b5
feat: Add a preference to hide "self-boosts"
A "self-boost" is someone boosting their own post. Some people are
particularly prolific at this, and it can clutter the timeline. Provide
a new preference that allows the user to show/hide these boosts from
their timeline.
2023-10-23 22:47:11 +02:00
Nik Clayton 42b09f4f1e
fix: Show full display and username in profile view (#195)
Most parts of the UI will truncate the display of long names (display
and user), but it makes sense to show them untruncated on the account's
profile screen.
2023-10-23 13:20:23 +02:00
Nik Clayton 5a41cbd40f
fix: Improve display of "obscured" links (#194)
The previous code (a) used an emoji as the prefix character when showing
the destination of an obscured link, and (b) made the destination part
of the link anchor text.

Using an emoji was a problem because the user can use different emoji
sets and it can give strange results. Making the destination part of the
link text made it difficult to distinguish at a glance where one link
ends and another starts.

Fix the emoji problem by replacing the emoji with a drawable.

Fix the destination problem by changing the string resource so it only
includes the destination part, and inserting it at the end of the link
instead of replacing the whole link. This means the disclosed
destination is not clickable, does not look like part of the link, and
stands out more.
2023-10-23 13:20:09 +02:00
Nik Clayton 566b23ed06
fix: Ensure empty timeline message is visible (#191)
Previously was showing pale text on a pale background, so effectively
invisible.

Use `colorPrimary` and `colorOnPrimary` to ensure the text can be seen.
2023-10-20 13:29:35 +02:00
Nik Clayton 514b295fe1
refactor: Use sealed interfaces for lighterweight code (#190)
Using a sealed interface (instead of a sealed class) at the root of the
hierarchy avoids the overhead of having to create and initialise the
class (visible in the generated bytecode).

It also makes the instantiation code slightly less cumbersome because
the code doesn't need to pass parameters to the root's constructor.
2023-10-20 13:00:36 +02:00
Nik Clayton d39eb3b642
refactor: Extract PreviewCard display code to `PreviewCardView` (#184) 2023-10-19 12:54:58 +02:00
Nik Clayton 3157f8d946
fix: Adjust video playback UX behaviour (#186)
Previously, playing a video would show the controls and associated
overlay for five seconds before fading them out. This obscures the video
for too long.

Fix this by:

- Only showing the media description on start, and remove after two
seconds
- Show the controls (and media description) if the user taps, removing
after two seconds
- Pausing the video (with the pause control, or tapping on the media
description) keeps the controls and description on-screen indefinitely
so they are easier to read

Fixes #144
2023-10-19 12:43:10 +02:00
Nik Clayton 0730c0190b
refactor: Use ksp instead of kapt for Hilt (#181)
This removes all use of kapt from the project.
2023-10-18 15:02:17 +02:00
Nik Clayton e59eebc5e4
fix: Use Pachli blue and orange for notification icons (#182)
Fixes #178
2023-10-17 20:35:15 +02:00
sanao 95d4fd2d74 fix(l10n): Update Japanese translations
Currently translated at 99.5% (627 of 630 strings)

Translation: Pachli/UI strings
Translate-URL: https://hosted.weblate.org/projects/pachli/ui-strings/ja/
2023-10-17 20:33:48 +02:00
Nik Clayton 2ca279a37c
fix: Update timeline when link preview setting changes (#180)
The previous code didn't include SHOW_CARDS_IN_TIMELINES in the list of
prefkeys that change `StatusDisplayOptions`, so changing the preference
wouldn't update the timeline display; you had to close/restart the app.
2023-10-16 21:49:11 +02:00
sanao 3cfb7a0d1e
feat: Show announcement dates (#35) (#151)
Display the time that an announcement was posted, as well as the
most recent update to the announcement (if there is one). Time display
honours the user's "use absolute time" preference.

Fixes #35
2023-10-16 20:04:30 +02:00
Nik Clayton db2bd3199e
refactor: Create repositories for preferences and StatusDisplayOptions (#149)
Previously, code for handling shared preferences, and how those
preferences affect `StatusDisplayOptions`, was scattered through the
code base with duplicate implementations.

Bring it together in to a `SharedPreferencesRepository` and a
`StatusDisplayOptionsRepository`.

`SharedPreferencesRepository` is a thin wrapper over`SharedPreferences`
that delegates most work to `SharedPreferences`. It configures a
listener for preference changes, and exposes those changes as a flow.

`StatusDisplayOptions` now contains explicit defaults to ensure they
are in one place.

`StatusDisplayOptionsRepository` exposes a `StatusDisplayOptions` flow
that updates whenever the active account changes or a relevant
preference changes.

The viewmodels expose `StatusDisplayOptionsRepository.flow` to the
activities and fragments so they can pass the current value to the
adapter.

This obsoletes `PreferenceChangedEvent`. An event is still fired when
filters change, `FilterChangedEvent`.

This allowed many of the mocks in tests to be replaced with either the
real type (because a fake is injected in to it, or one of its
dependencies) or a custom fake that provides a mock.
2023-10-15 22:52:47 +02:00
Nik Clayton 24fa26c126
refactor: Simplify View{Image,Media,Video}Fragment creation (#175)
Previous code had to distinguish between showing an attachment or
showing an image by URL.

Simplify this by -- in the image URL case -- creating a fake attachment
that references the image URL.

Move the code that unmarshalls the Bundle arguments to
`ViewMediaFragment` to share between `ViewImageFragment` and
`ViewVideoFragment`.
2023-10-15 22:29:18 +02:00
Nik Clayton c50f10a989
refactor: Extract Poll display code to `PollView` (#177) 2023-10-15 22:26:34 +02:00
Nik Clayton 9cb41d6353
fix: Show media when resuming ViewMediaFragment (#174)
Previous code finalised the view setup in `onViewCreated`, so if you
opened some media, switched away from the app, and switched back you'd
get a blank screen.

Fix this by doing the finalisation in `onResume()`, so the media is
displayed correctly when returning to the fragment.

Fixes #161
2023-10-15 14:45:41 +02:00
Nik Clayton 99dd15ea89
fix: Add foregroundServiceType/onTimeout() to prevent crash (#163)
Android 14 (SDK 34) requires a `foregroundServiceType` and `onTimeout()`
implementation for foreground services, otherwise creating the service
will crash.

Do this. If `SendStatusService` does timeout then any pending statuses
are marked as failed, saved to drafts, and the user is informed.

Fixes #162
2023-10-15 13:07:35 +02:00
Weblate (bot) 34c53a67e0
fix(l10n): Translations update from Weblate (#159)
Translations update from [Hosted Weblate](https://hosted.weblate.org)
for [Pachli/Fastlane
Metadata](https://hosted.weblate.org/projects/pachli/fastlane-metadata/).


It also includes following components:

* [Pachli/UI
strings](https://hosted.weblate.org/projects/pachli/ui-strings/)



Current translation status:

![Weblate translation
status](https://hosted.weblate.org/widget/pachli/fastlane-metadata/horizontal-auto.svg)

---------

Co-authored-by: sanao <jinsei@sanao.dev>
Co-authored-by: Eryk Michalak <gnu.ewm@protonmail.com>
2023-10-15 11:48:52 +02:00
renovate[bot] ca06d46d32
fix(deps): update glide to v4.16.0 (#123)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
|
[com.github.bumptech.glide:okhttp3-integration](https://togithub.com/bumptech/glide)
| `4.15.1` -> `4.16.0` |
[![age](https://developer.mend.io/api/mc/badges/age/maven/com.github.bumptech.glide:okhttp3-integration/4.16.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.github.bumptech.glide:okhttp3-integration/4.16.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.github.bumptech.glide:okhttp3-integration/4.15.1/4.16.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.github.bumptech.glide:okhttp3-integration/4.15.1/4.16.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [com.github.bumptech.glide:glide](https://togithub.com/bumptech/glide)
| `4.15.1` -> `4.16.0` |
[![age](https://developer.mend.io/api/mc/badges/age/maven/com.github.bumptech.glide:glide/4.16.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.github.bumptech.glide:glide/4.16.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.github.bumptech.glide:glide/4.15.1/4.16.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.github.bumptech.glide:glide/4.15.1/4.16.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [com.github.bumptech.glide:ksp](https://togithub.com/bumptech/glide) |
`4.15.1` -> `4.16.0` |
[![age](https://developer.mend.io/api/mc/badges/age/maven/com.github.bumptech.glide:ksp/4.16.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.github.bumptech.glide:ksp/4.16.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.github.bumptech.glide:ksp/4.15.1/4.16.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.github.bumptech.glide:ksp/4.15.1/4.16.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>bumptech/glide
(com.github.bumptech.glide:okhttp3-integration)</summary>

###
[`v4.16.0`](https://togithub.com/bumptech/glide/releases/tag/v4.16.0):
Glide 4.16.0

This release focuses on some build improvements and Compose. The two
major Compose improvements are adding support for Compose specific
transitions (e.g. cross fade) and supporting recomposition based on
request state using `GlideSubcomposition`. There's also been a bunch of
internal refactoring to move away from Painters to Modifier nodes based
on feedback from the Compose team. This is still an alpha release of
Compose, but barring unexpectedly negative feedback, the next release
should be beta.

This should be the last release of Glide that targets Java 7. That
probably means our next release will be a major version change.

##### Features

- Allow passing an executor into ChromiumRequestSerializer in
[https://github.com/bumptech/glide/pull/5077](https://togithub.com/bumptech/glide/pull/5077)
- Allow host app to provide a way to clear all resources onStop() by
[@&#8203;osamaaftab](https://togithub.com/osamaaftab) in
[https://github.com/bumptech/glide/pull/5145](https://togithub.com/bumptech/glide/pull/5145)

##### Compose

- Add a Transition API and a CrossFade Transition for Compose by
[@&#8203;sjudd](https://togithub.com/sjudd) in
[https://github.com/bumptech/glide/pull/5235](https://togithub.com/bumptech/glide/pull/5235)

- Influence layout using intrinsics in GlideNode by
[@&#8203;sjudd](https://togithub.com/sjudd) in
[https://github.com/bumptech/glide/pull/5240](https://togithub.com/bumptech/glide/pull/5240)
\* Log instead of throwing parsing manifests to fix compose previews by
[@&#8203;sjudd](https://togithub.com/sjudd) in
[https://github.com/bumptech/glide/pull/5167](https://togithub.com/bumptech/glide/pull/5167)

- Launch no more than one request per onRemembered by
[@&#8203;sjudd](https://togithub.com/sjudd) in
[https://github.com/bumptech/glide/pull/5062](https://togithub.com/bumptech/glide/pull/5062)

- Remove GlidePainter in favor of Modifier nodes / Flows by
[@&#8203;sjudd](https://togithub.com/sjudd) in
[https://github.com/bumptech/glide/pull/5230](https://togithub.com/bumptech/glide/pull/5230)

- Replace flows in GlideSubcomposition with a listener on GlideNode by
[@&#8203;sjudd](https://togithub.com/sjudd) in
[https://github.com/bumptech/glide/pull/5238](https://togithub.com/bumptech/glide/pull/5238)

##### Bugs

- Read library glide module names from Java indexes by
[@&#8203;sjudd](https://togithub.com/sjudd) in
[https://github.com/bumptech/glide/pull/5052](https://togithub.com/bumptech/glide/pull/5052)
- Fix typo. anay -> any in GlideSymbolProcessor.kt. by
[@&#8203;trevorhackman](https://togithub.com/trevorhackman) in
[https://github.com/bumptech/glide/pull/5029](https://togithub.com/bumptech/glide/pull/5029)
- Include URL in error log by
[@&#8203;paulsowden](https://togithub.com/paulsowden) in
[https://github.com/bumptech/glide/pull/5164](https://togithub.com/bumptech/glide/pull/5164)
- Add `isInitialized` visible for testing method by
[@&#8203;paulsowden](https://togithub.com/paulsowden) in
[https://github.com/bumptech/glide/pull/5163](https://togithub.com/bumptech/glide/pull/5163)
- Use onIdle to avoid a race in FlowTests by
[@&#8203;sjudd](https://togithub.com/sjudd) in
[https://github.com/bumptech/glide/pull/5202](https://togithub.com/bumptech/glide/pull/5202)
- Add a isEquivalentTo method to correctly check equality by
[@&#8203;mori-atsushi](https://togithub.com/mori-atsushi) in
[https://github.com/bumptech/glide/pull/5232](https://togithub.com/bumptech/glide/pull/5232)
- Add
[@&#8203;RequiresPermission](https://togithub.com/RequiresPermission) to
NotificationTarget by
[@&#8203;TWiStErRob](https://togithub.com/TWiStErRob) in
[https://github.com/bumptech/glide/pull/5220](https://togithub.com/bumptech/glide/pull/5220)

##### Deprecations

- `placeholderOf(@&#8203;Composable)` in `GlideImage` is deprecated, use
`GlideSubcomposition` instead. Keep in mind that using either forces a
recomposition each time the state of the image load changes.
Recomposition will have a significant performance penalty in scrolling
lists and should be avoided.

##### Behavior Changes

- Hard code disabling hardware bitmaps on O/OMR1. by
[@&#8203;sjudd](https://togithub.com/sjudd) in
[https://github.com/bumptech/glide/pull/5115](https://togithub.com/bumptech/glide/pull/5115)
- Do not set requireOriginal on Android photo picker uris. by
[@&#8203;phoenixli](https://togithub.com/phoenixli) in
[https://github.com/bumptech/glide/pull/5162](https://togithub.com/bumptech/glide/pull/5162)

##### Breaking Changes

##### Build Changes

- Add integration tests for ksp library modules. by
[@&#8203;sjudd](https://togithub.com/sjudd) in
[https://github.com/bumptech/glide/pull/5054](https://togithub.com/bumptech/glide/pull/5054)
- Update README.md to use https by
[@&#8203;simoarpe](https://togithub.com/simoarpe) in
[https://github.com/bumptech/glide/pull/5058](https://togithub.com/bumptech/glide/pull/5058)
- Use dokka to build scripts/update_javadocs.sh by
[@&#8203;sjudd](https://togithub.com/sjudd) in
[https://github.com/bumptech/glide/pull/5104](https://togithub.com/bumptech/glide/pull/5104)
- avif integration: Update libavif dependency by
[@&#8203;vigneshvg](https://togithub.com/vigneshvg) in
[https://github.com/bumptech/glide/pull/5128](https://togithub.com/bumptech/glide/pull/5128)
- Disable java 7 source obsolete warning. by
[@&#8203;sjudd](https://togithub.com/sjudd) in
[https://github.com/bumptech/glide/pull/5168](https://togithub.com/bumptech/glide/pull/5168)
- Update mockito version to fix j16 compilation. by
[@&#8203;sjudd](https://togithub.com/sjudd) in
[https://github.com/bumptech/glide/pull/5169](https://togithub.com/bumptech/glide/pull/5169)
- Switch Glide's dependencies to a version catalog. by
[@&#8203;sjudd](https://togithub.com/sjudd) in
[https://github.com/bumptech/glide/pull/5183](https://togithub.com/bumptech/glide/pull/5183)
- Remove jetifier by [@&#8203;sjudd](https://togithub.com/sjudd) in
[https://github.com/bumptech/glide/pull/5184](https://togithub.com/bumptech/glide/pull/5184)
- Add an updated proguard plugin to compile on Java 17. by
[@&#8203;sjudd](https://togithub.com/sjudd) in
[https://github.com/bumptech/glide/pull/5185](https://togithub.com/bumptech/glide/pull/5185)
- Configure Renovate in
[https://github.com/bumptech/glide/pull/5186](https://togithub.com/bumptech/glide/pull/5186)
- Increment ROBOLECTRIC_SDK to 19 from 18. by
[@&#8203;brettchabot](https://togithub.com/brettchabot) in
[https://github.com/bumptech/glide/pull/5208](https://togithub.com/bumptech/glide/pull/5208)
and
[https://github.com/bumptech/glide/pull/5207](https://togithub.com/bumptech/glide/pull/5207)
- AGP: Upgrade AndroidManifest.xml's package to build.gradle's
namespace. by [@&#8203;TWiStErRob](https://togithub.com/TWiStErRob) in
[https://github.com/bumptech/glide/pull/5221](https://togithub.com/bumptech/glide/pull/5221)

##### New Contributors

- [@&#8203;trevorhackman](https://togithub.com/trevorhackman) made their
first contribution in
[https://github.com/bumptech/glide/pull/5029](https://togithub.com/bumptech/glide/pull/5029)
- [@&#8203;simoarpe](https://togithub.com/simoarpe) made their first
contribution in
[https://github.com/bumptech/glide/pull/5058](https://togithub.com/bumptech/glide/pull/5058)
- [@&#8203;paulsowden](https://togithub.com/paulsowden) made their first
contribution in
[https://github.com/bumptech/glide/pull/5164](https://togithub.com/bumptech/glide/pull/5164)
- [@&#8203;phoenixli](https://togithub.com/phoenixli) made their first
contribution in
[https://github.com/bumptech/glide/pull/5162](https://togithub.com/bumptech/glide/pull/5162)
- [@&#8203;osamaaftab](https://togithub.com/osamaaftab) made their first
contribution in
[https://github.com/bumptech/glide/pull/5145](https://togithub.com/bumptech/glide/pull/5145)
- [@&#8203;brettchabot](https://togithub.com/brettchabot) made their
first contribution in
[https://github.com/bumptech/glide/pull/5207](https://togithub.com/bumptech/glide/pull/5207)
- [@&#8203;mori-atsushi](https://togithub.com/mori-atsushi) made their
first contribution in
[https://github.com/bumptech/glide/pull/5232](https://togithub.com/bumptech/glide/pull/5232)

**Full Changelog**:
https://github.com/bumptech/glide/compare/v4.15.0...v4.16.0

Note - there's been a change in the gpg key used to sign these releases.
The new public key is attached

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these
updates again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/pachli/pachli-android).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4xMDcuMiIsInVwZGF0ZWRJblZlciI6IjM3LjguMSIsInRhcmdldEJyYW5jaCI6Im1haW4ifQ==-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Nik Clayton <nik@ngo.org.uk>
2023-10-13 14:59:45 +02:00
Nik Clayton 71df6254ef
fix: Show thread indicators and other dividers using Material colours (#157)
Use the Material colour for `conversation_thread_line` (which is
`colorOutlineVariant`) instead of a custom attribute.

Elsewhere, use the Material attribute directly (in code), or replace the
custom divider with a `MaterialDivider`.

This makes some colour definitions unused, so remove them.

Fixes #148
2023-10-13 11:36:05 +02:00
Nik Clayton ff5d7f1d27
refactor: Update ViewThreadViewModel to use FiltersRepository (#156)
Instead of calling the filters API directly use `FiltersRepository` to
handle the v1/v2 filter differences.
2023-10-12 12:47:27 +02:00
Nik Clayton 0902b0ba49
refactor: Replace test preference mocks with InMemorySharedPreferences (#155)
Previously the tests mocked shared preferences with a map and a mock
that had to be implemented for each test that needed it.

Replace this with `InMemorySharedPreferences`, which provides the normal
`SharedPreferences` interface so can be used as a drop-in replacement.
2023-10-12 11:22:41 +02:00
Nik Clayton 628b5a7db5
refactor: Inject Gson in FakeDatabaseModule (#153) 2023-10-11 21:27:28 +02:00
Nik Clayton f88599908b
refactor: Extract FakeMastodonApiModule (#152)
Extract `FakeMastodonApiModule` from `ComposeActivityTest` to make it
usable in other tests. Update `MainActivityTest` to use the extracted
code.
2023-10-11 15:39:51 +02:00
Nik Clayton 53e7842439
change: Increase compileSdk and targetSdk to 34 (#150)
Associated changes:

- Handle new null/non-null type signatures in overriden methods
- Configure Robolectric to use SDK 33 (current highest supported
version)
2023-10-11 12:28:45 +02:00
Nik Clayton 38214648dd
refactor: Migrate from Dagger to Hilt (#143)
- Remove `Injectable` interface, use `@AndroidEntryPoint`
- Remove `DispatchingAndroidInjector`
- Remove `viewModelFactory`, use `@HiltViewModel`
- Create providers for the different DAOs, and inject those instead of
  `AppDatabase`
- Create provider for a database transaction, inject that instead of
  `AppDatabase`
- Update tests
2023-10-07 19:30:11 +02:00
Nik Clayton f4c0d3525b
chore: Prepare release 1.2.2 (versionCode 5) (#140) 2023-10-03 13:21:53 +02:00
Nik Clayton 802cdd4c46
feat: Embed the privacy policy in the app (#139)
Instead of linking to the privacy policy embed it in the app as a string
of HTML.

The string is created with a new `markdown2resource` plugin, which
converts `PRIVACY.md` to HTML and generates a Java class with the HTML
content.

Create `PrivacyPolicyActivity` to display the HTML in a `WebView`, and
link to it from `AboutActivity`.
2023-10-03 12:56:30 +02:00
Nik Clayton 2cc534f22a
chore: Prepare release 1.2.1 (versionCode 4) (#138) 2023-09-30 14:33:10 +02:00
Nik Clayton 651b0efcd6
feat: Link to the privacy policy from "About" (#137)
Google requires an in-app link to the privacy policy.
2023-09-30 13:15:44 +02:00
Nik Clayton 7b4d879e80
chore: Prepare release 1.2 (versionCode 3) (#135) 2023-09-29 15:49:43 +02:00
Nik Clayton 6fedfe54ba
fix: Restore the user's reading position under all circumstances (#133)
The previous code did not always work when the user returned to the app
after a lengthy absence (e.g., overnight).

Instead of restoring by scrolling in `TimelineFragment`, restore by
working with the platform.

Determine the initial page to fetch by looking half a page ahead of the
saved saved status ID, and fetch that status and the page immediately
prior. This seems to match the view's expectations about what will be
immediately available.

Set `jumpThreshold` and `enablePlaceholders` in the `PagingConfig` so
the paging system will jump to the saved status.

Remove the restoration code in `TimelineFragment`.

Fixes #53
2023-09-29 11:10:55 +02:00
Nik Clayton d434144922
ci: Upload orangeRelease to Google Play (internal track) (#134)
Start building infrastructure to automatically build and deploy the
`orangeRelease` variant to Google Play.

The variant needs an automatically incrementing `versionCode`. That is
derived from the count of all commits.

Change the separator between the version and the build metadata in the
`versionName` from `-` to `+` to be consistent with semantic versioning.

This is still an experiment, so the workflow is triggered manually and
only uploads to the internal track
2023-09-28 13:50:02 +02:00
Nik Clayton b947c1b289
fix: Improve error handling when blocking accounts (#131)
The previous code ran the API call in a `try/catch block`, and handled
errors in the `catch`. But `NetworkResult` already catches the exception
and transforms it to a failure, so the error case was not handled.

Replace with `NetworkResult.fold`.
2023-09-27 18:32:58 +02:00
Nik Clayton 50d9aedad9
chore(deps): Update to AGP 8.1.1 (#130) 2023-09-27 18:06:14 +02:00
Nik Clayton 0b8d702960
refactor: Remove duplicate `MainCoroutineRule` (#129) 2023-09-27 17:53:24 +02:00
Nik Clayton c5a5540467
refactor: Remove rxjava3 from Mastodon API spec (#128)
Remove the rxjava3 `Single` type from the MastodonAPI definition,
replacing with `Response` or `NetworkResult` as appropriate.

Update callsites and tests as appropriate.

This removes the need for `com.squareup.retrofit2:adapter-rxjava3`
2023-09-27 11:35:55 +02:00
Nik Clayton 11fecb1914
feat: Show vertical scrollbars on scrollable lists (#96)
Display normal Android (i.e., fading) scrollbars when the user scrolls
in lists.
2023-09-26 15:57:35 +02:00
Nik Clayton 04025e99ff
fix: Show media when opening a thread, based on user preferences (#93)
A previous change dropped the check to see if media was marked as
sensitive, and so all media was hidden when viewing a thread. Reinstate
the check so only sensitive media is hidden (if the user preferences are
set that way).
2023-09-24 21:23:29 +02:00
Nik Clayton 9b21f3f9bf
refactor: Ensure `statusDisplayOptions` are created consistently (#92)
Previous code created `statusDisplayOptions` in full each time, risking
the creation of inconsistent states / defaults.

Refactor to use `StatusDisplayOptions.from()` so the user's settings
(and defaults) are always respected.
2023-09-24 21:23:07 +02:00
Nik Clayton af7b668476
fix: Enable/disable vote button when the user can/can't vote (#91)
Previously the voting button was always enabled, even if the user hadn't
made a choice.

Disable the button by default, and listen for clicks on the options.
Enable the button whenever one or more options are selected.

Fixes #90
2023-09-23 21:01:33 +02:00
Nik Clayton 2169c91281 fix: Ensure `setLifeOnScrollTargetView` is called when fragment resumes
If you do not do this and the fragment is in a pager then it can be
overridden when another fragment is swiped in to view.
2023-09-23 16:21:05 +02:00