Commit Graph

305 Commits

Author SHA1 Message Date
Nik Clayton 01831474dc
feat: Toggle display of search operators with toolbar action (#836)
Default to hiding the search operators, and provide a new toolbar icon
(always visible) to show them.

The toolbar icon is displayed with a badge if any operators are present.

Adjust the operator display to three horizontal scrolling rows, to
further limit the maximum amount of vertical space the operators use.
2024-07-24 18:51:00 +02:00
Nik Clayton 71e006b0d2
feat: Provide a UI to edit different search operators (#829)
Mastodon supports in-query search operators, such as `has:image`,
`language:en`, or `in:library`. Previously the user had to enter them in
to the query directly.

This provides a chip-based UI that allows the user to set values for
these operators.

## Server

- Add new search capabilities to record the faceted search features the
server reports.
- Update definitions for Mastodon, Friendica, and GoToSocial to specify
which versions of the operations they support.

## SearchOperator / SearchOperatorViewData

- Represents each supported operator and associated viewdata.

## SearchActivity / activity_search.xml

- Conditionally display a chip for each facet depending on the server's
level of support.
- Implement the UI for each chip. They display dialogs of varying levels
of complexity depending on the underlying operation.

## FragmentSearch

- Display the progress as a LinearProgressIndicator instead of an
indeterminate ProgressBar. This makes it more visible under the search
facets.
2024-07-22 17:11:08 +02:00
Nik Clayton e063ae69e6
fix: Support same capabilities on Glitch as Mastodon (#828)
The Glitch fork reports the same version number as stock Mastodon and is
supposed to have the same baseline capabilities as stock Mastodon at
that version number.
2024-07-22 16:37:26 +02:00
Nik Clayton 526ee27a6a
fix: Enable server filtering on GoToSocial 0.16+ (#826)
Previous code had the version test in the wrong order, so the check for
>= 0.15.0 took precedence.
2024-07-22 16:22:01 +02:00
Nik Clayton 92e5304b84
fix: Use colorPrimary for checked/selected dialog items (#825)
RadioButton and CheckBox color the selected radio button or check box
using `colorPrimary`. For some reason Material dialogs don't, and use
`colorSecondary` for this (and only this), which leads to visual
inconstencices through the app.

Fix this by setting `colorSecondary` to `colorPrimary` to force it.
2024-07-22 16:19:08 +02:00
Nik Clayton 6b55d107c1
feat: Edit a matching filter directly from the timeline (#819)
Previously, if a status was filtered with "WARN" and was shown in the
timeline with the name of the filter, and the user then decided to
change
that filter, they had to:

1. Open the left navigation menu
2. Navigate to "Account preferences"
3. Open "Filters"
4. Find the filter they want to edit, tap it
5. Make the change, and save
6. "Back" to the list of filters
7. "Back" to "Account preferences"
8. "Back" to the timeline

That's a lot of clicks for a simple action.

Change this. Now the filtered status includes an "Edit filter" button
that takes the user directly to step 5, and when they press "Back" they
return directly to the timeline.

To do this create a new filter action, `onEditFilterById`. Update the
listeners to launch `EditFilterActivity` if appropriate.

Modify `item_status_filtered.xml` to show the new button.

Update the accessibility delegate to show just the "Show anyway" and
"Edit filter" actions. Modify `FilterableStatusViewHolder` to expose
the information it needs to do this.
2024-07-19 13:45:24 +02:00
Nik Clayton b878211891
feat: Show a specific message if requests are rate-limited (#818) 2024-07-14 23:43:10 +02:00
Nik Clayton 00a2cd32d3
change: Implement more of FiltersRepository (#816)
The previous code had a number of problems, including:

- Calls to the filters API were scattered through UI and viewmodel code.
- Repeated places where the differences between the v1 and v2 Mastodon
filters API had to be handled.
- UI and viewmodel code using the network filter classes, which tied
them to the API implementation.
- Error handling was inconsistent.

Fix this.

## FiltersRepository

- All filter management now goes through `FiltersRepository`.
- `FiltersRepository` exposes the current set of filters as a
`StateFlow`, and automatically updates it when the current server
changes or any changes to filters are made. This makes
`FilterChangeEvent` obsolete.
- Other operations on filters are exposed through `FiltersRepository` as
functions for viewmodels to call.
- Within the bulk of the app a new `Filter` class is used to represent a
filter; handling the differences between the v1 and v2 APIs is
encapsulated in `FiltersRepository`.
- Represent errors when handling filters as subclasses of `PachliError`,
and use `Result<V, E>` throughout, including using `ApiResult` for all
filter API results.
- Provide different types to distinguish between new-and-unsaved
filters, new-and-unsaved keywords, and in-progress edits to filters.

## Editing filters

- Accept an optional complete filter, or filter ID, as parameters in the
intent that launches `EditFilterActivity`. Pass those to the viewmodel
using assisted injection so the viewmodel has the info immediately.
- In the viewmodel use a new `FilterViewData` type to model the data
used to display and edit the filter.
- Start using the UiSuccess/UiError model. Refrain from cutting over to
full the action implementation as that would be a much larger change.
- Use `FiltersRepository` instead of making any API calls directly.

## Listing filters

- Use `FiltersRepository` instead of making any API calls directly.

## EventHub

- Remove `FilterChangedEvent`. Update everywhere that used it to use the
flow from `FiltersRepository`.
2024-07-14 15:36:52 +02:00
Aindriú Mac Giolla Eoin ba23edfc57 fix(l10n): Update Irish translations
Currently translated at 100.0% (10 of 10 strings)

Translation: Pachli/Core/Network : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/corenetwork-main/ga/
2024-07-13 09:43:18 +02:00
Aindriú Mac Giolla Eoin e8c6093d90 fix(l10n): Update Irish translations
Currently translated at 100.0% (6 of 6 strings)

Translation: Pachli/Core/Data : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/coredata-main/ga/
2024-07-13 09:43:18 +02:00
Aindriú Mac Giolla Eoin 9b55e5cdf7 fix(l10n): Update Irish translations
Currently translated at 100.0% (3 of 3 strings)

Translation: Pachli/Core/Activity : Orange
Translate-URL: https://hosted.weblate.org/projects/pachli/coreactivity-orange/ga/
2024-07-13 09:43:18 +02:00
Miles Krell bb6cff1abb fix(l10n): Update Spanish translations
Currently translated at 100.0% (10 of 10 strings)

Translation: Pachli/Core/Network : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/corenetwork-main/es/
2024-07-13 09:43:18 +02:00
Aindriú Mac Giolla Eoin 3a535aa0bf fix(l10n): Update Irish translations
Currently translated at 100.0% (14 of 14 strings)

Translation: Pachli/Core/Ui : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/coreui-main/ga/
2024-07-13 09:43:18 +02:00
Aindriú Mac Giolla Eoin f28b8e7717 fix(l10n): Update Irish translations
Currently translated at 100.0% (4 of 4 strings)

Translation: Pachli/Core/Activity : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/coreactivity-main/ga/
2024-07-13 09:43:18 +02:00
sunniva a37a971257 fix(l10n): Update Norwegian Bokmål translations
Currently translated at 100.0% (4 of 4 strings)

Translation: Pachli/Core/Activity : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/coreactivity-main/nb_NO/
2024-07-08 00:11:01 +02:00
Nik Clayton 0f80ec4abf
fix: Correctly punctuate a status content description (#808)
Previous code blindly inserted commas and semi-colons as separators
between the components of a content description. If some of those
components were null you could have a content description that looked
like "... , , , ..." or similar, and the repeated reading of "comma" by
screen readers was jarring and reduced accessibility.

Fix this by inserting punctuation only where necessary, building up the
string piece by piece instead of using a string resource with hardcoded
punctuation.

Fixes #791.
2024-07-06 19:29:02 +02:00
Nik Clayton 4dac29cc52
feat: Show autocomplete hashtags with usage counts, sort by popularity (#807)
When autocompleting hashtags while composing a status the previous code
showed the hashtags in the same order they're returned by the server,
with no additional information.

This doesn't allow the user to make an informed choice about which
hashtag might be better to use. For example, trying to choose between
"#nivenly" and "#NivenlyFoundation".

To fix that, include the hashtag's usage when receiving data from the
server. Sum that, and show it to the user in the hashtag list. Sort the
hashtags by popularity, most popular first.
2024-07-06 14:25:46 +02:00
Nik Clayton ea05dec6c5
feat: Show author bylines on preview cards, tap to view profile (#805)
Mastodon now supports additional (optional) author information to show
as a byline on preview cards.

Use this (if included), to show the author's avatar, name, and link to
their profile. If tapped a click on a new `Target.BYLINE` target is
registered allowing fragments/activities to launch
`ViewProfileActivity`.

Include this as an action in `ListStatusAccessibilityDelegate`, and
provide `TrendingLinksAccessibilityDelegate` to provide accessibility
actions when viewing trending links.
2024-07-06 00:30:24 +02:00
Nik Clayton 5aacb02ea0
feat: Provide more detail in errors, especially media upload errors (#801)
Previous code assumed server responses would always be JSON, and had no
special handling for mis-configured servers that sometimes return HTML;
for example, if the server has a bug, or there's a reverse proxy in
front of the server issuing DoS-prevention challenges.

This could cause errors to show with no useful debugging information.

Update `ApiResult` to check the content-type in the response and return
one of two new errors if the content-type is missing or wrong. Also
include the HTTP code in `ApiResponse` for use elsewhere.

Update `ThrowableExtensions` to pull the `error` and optional
`description` out of the error body.

Update `PachliError` so `formatArgs` can be an array of arbitrary types,
not just strings.

Update `MediaUploader`; expose the different errors as new
`MediaUploaderError` types instead of `Exception` subclasses, and return
`Result<V, E>` where appropriate.

Update `ComposeViewModel` to use the new `MediaUploaderError` types and
create new `PickMediaError` to report issues there, replacing
`VideoOrImageException`.

Update `ComposeActivity` to use the new error types and show errors
until the user dismisses them, so they're better able to see and report
problems.

Fixes #704.
2024-07-04 19:16:24 +02:00
Nik Clayton f477c63ab4
fix: Improve readability of status media labels (#778)
Previous code did not provide whitespace between different media labels
when media is not loaded.

In addition, the icon for the media was centre-aligned vertically with
the text, making it difficult to scan and determine when one media label
ends and another one starts.

Fix this by adding an 8dp margin between the media labels, and using a
TextView subclass that vertically aligns the media icon with the first
line of text.

Set the compound drawables with relative alignment, so they behave
appropriately in RTL layouts.

Fixes #751.
2024-06-25 11:53:47 +02:00
Nik Clayton 1f2194cc3e
fix: Ensure text in nav menu account header is legible (#773)
The user might have set a profile header image that is close to the
colour of the text in the account header in the left navigation menu.
This can make the text difficult or impossible to see.

Work around this by drawing a partially transparent scrim behind the
text so it's always displayed over a background that makes the text
legible.

Fixes #298
2024-06-22 16:55:57 +02:00
Nik Clayton 33e1b418cf
refactor: Improve blurhash decoding performance (#770)
By Christophe Beyls in https://github.com/tuskyapp/Tusky/pull/4515.
Their commit notes:

Improve the performance of `BlurHashDecoder` while also reducing memory
allocations.

- Precompute cosines tables before composing the image so each cosine
value is only computed once.
- Compute cosines tables once if both are identical (for square images
with the same number of colors in both dimensions).
- Store colors in a one-dimension array instead of a two-dimension array
to reduce memory allocations.
- Use a simple String.indexOf() to find the index of a Base83 char,
which is both faster and needs less memory than a HashMap thanks to
better locality and no boxing of chars.
- No cache is used, so computations may be performed in parallel on
background threads without the need for synchronization which limits
throughput.
2024-06-20 13:19:15 +02:00
Nik Clayton f3354d1aae
refactor: Improve IO performance and simplify code with Okio (#769)
`ImageDownsizer.downsizeImage()`:
- Remove the return value, it was ignored
- Throw `FileNotFoundException` when `openInputStream` returns null

`ImageDownsizer.getImageOrientation()`:
- Throw `FileNotFoundException` when `openInputStream` returns null

`MediaUploader.prepareMedia()`:
- Copy URI contents using Okio buffers / source / sink

`UriExtensions`:
- Rename from `IOUtils`
- Implement `Uri.copyToFile()` using Okio buffers / source / sink
- Replace `ProgressRequestBody()` with `Uri.asRequestBody()` using Okio
buffers / source / sink

`DraftHelper.copyToFolder()`
- Use Okio buffers / source / sink

`CompositeWithOpaqueBackground`
- Use constants `SIZE_BYTES` and `CHARSET` instead of magic values
- Use `Objects.hash` when hashing multiple objects

Based on work by Christophe Beyls in
- https://github.com/tuskyapp/Tusky/pull/4366
- https://github.com/tuskyapp/Tusky/pull/4372
2024-06-20 13:18:58 +02:00
Nik Clayton 4551313bd2
refactor: Use androidx.core:core-splashscreen library (#766)
Previous code depended on, but did not initialise, the androidx
splashscreen library.

Fix that, using the library on API < 31, or the platform implementation
otherwise.

`SplashActivity` is no longer needed, launching goes straight in to
`MainActivity`.

Version 1.2.0-alpha01 is needed to fix some theme corruption bugs in
earlier versions of the library.
2024-06-19 16:27:49 +02:00
Nik Clayton da01241874
feat: Support server filters in GoToSocial 0.16.0 (#765) 2024-06-19 14:38:01 +02:00
renovate[bot] 0e150c7b45
fix(deps): update dependency com.google.android.material:material to v1.12.0 (#692)
[![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.google.android.material:material](https://togithub.com/material-components/material-components-android)
| `1.11.0` -> `1.12.0` |
[![age](https://developer.mend.io/api/mc/badges/age/maven/com.google.android.material:material/1.12.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/com.google.android.material:material/1.12.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/com.google.android.material:material/1.11.0/1.12.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.google.android.material:material/1.11.0/1.12.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

> [!WARNING]
> Some dependencies could not be looked up. Check the Dependency
Dashboard for more information.

---

### Release Notes

<details>
<summary>material-components/material-components-android
(com.google.android.material:material)</summary>

###
[`v1.12.0`](https://togithub.com/material-components/material-components-android/releases/tag/1.12.0)

[Compare
Source](https://togithub.com/material-components/material-components-android/compare/1.11.0...1.12.0)

### What's new since 1.11.0

- `Slider` and `Progress Indicator` have been updated to better support
Non-Text Contrast Accessibility requirements.
- Predictive Back Fragment/View support added to Material motion
transitions (`MaterialSharedAxis`, `MaterialFadeThrough`,
`MaterialFade`, `MaterialElevationScale`).

#### Important

Required `minSdkVersion` is now 19 or higher, for Material and AndroidX
([blog
post](https://android-developers.googleblog.com/2023/10/androidx-minsdkversion-19.html)).

#### Dependency Updates

| Dependency | Previous version | New version |
| - | - | - |
| androidx.transition | 1.2.0 | 1.5.0 |

#### Library Updates

-   `Gradle`
- Update library minSdkVersion to 19.
([`1bbb43d`](1bbb43d155))
- Upgrade to //third_party/gradle to 8.4
([`1756f23`](1756f233ec))
-   `Carousel`
- Shifted keylines in contained strategies when there exists padding,
and clipToPadding=false
([`1ef42e2`](1ef42e2f23))
- Fixed Javadoc formatting error in `FullScreenCarouselStrategy` class
documentation.
([`a0a1c6e`](a0a1c6e044))
- Added support for cross axis wrap_content RecyclerViews
([`e88a1b9`](e88a1b98d2))
- Added documentation recommending snapping for multi-browse strategy
([`9e64a1f`](9e64a1f5f6))
- Add attributes to change small item size
([`92a5444`](92a5444de9))
-   `CollapsingToolbarLayout`
- Fix text shadow fading when transitioning between expanded and
collapsed states
([`7674e12`](7674e12ea8))
-   `Checkbox`
- Updated string translations
([`198e08c`](198e08cf5e))
-   `Dialog`
- Unified scrim opacity in Material themes/theme overlays.
([`f3e4439`](f3e4439ca6))
-   `Divider`
- Fixed divider instantly appearing or disappearing on insertion or
removal
([`ef4a0c5`](ef4a0c5e36))
-   `i18n`
- Update translated strings
([`a8307ef`](a8307ef792))
-   `MaterialDatePicker`
- Fix date validation on Samsung devices
([`5aa6edf`](5aa6edfaed))
-   `MaterialAutoCompleteTextView`
- Enabled switch access in MaterialAutoCompleteTextView.
([`14a7b40`](14a7b40363))
-   `NavigationDrawer`
- Fixed wrong item selected after click
([`a3af20a`](a3af20a869))
-   `NavigationRail`
- Added label padding for when the label is long enough to reach the
sides of the nav rail
([`2439dc0`](2439dc0e81))
- Increased padding in between items as per design specs
([`16eca7e`](16eca7eef3))
-   `Predictive Back`
- Animated corners during predictive back when no drawerLayoutCornerSize
is set
([`c8b9b1c`](c8b9b1c0bb))
-   `ProgressIndicator`
- Updated inactive track color from primary container to secondary
container.
([`c8cb0c6`](c8cb0c6037))
- Updated the setter of track thickness to not update track corner
radius.
([`540f5ee`](540f5ee983))
- Added the limit to not have stop indicator size bigger than track
thickness.
([`689e04f`](689e04f9ed))
- Fixed the rounded ends overlapping bug with semi-transparent
track/indicator color in Circular default style.
([`8167c11`](8167c115e3))
- Removed the call to draw a transparent full track.
([`3f80fdb`](3f80fdb9e1))
- Flipped the canvas for different circular directions.
([`bcc27a3`](bcc27a3638))
- Split stop indicator drawing from indicator drawing.
([`76207cb`](76207cb270))
- Added ActiveIndicator to improve readability.
([`6fd920a`](6fd920a2c1))
- Fixed ESCAPE animation in linear and added ESCAPE animation in
circular.
([`98284e7`](98284e74ad))
- Updated to use the same drawing delegate object between determinate
drawable and indeterminate drawable to prevent inconsistent drawings
when specs update.
([`52b4845`](52b48450fc))
- Added missing graphics updates when spec changes.
([`93b3010`](93b30109b0))
- Update styles for new Accessibility updates
([`15b533f`](15b533fffb))
- Added static drawable for Circular type when system animator is
disabled.
([`22e054b`](22e054ba68))
-   `Search`
- Excluded icons from search bar handwriting bounds
([`387f59b`](387f59b706))
- Made `searchbar_scrolling_view_behavior` string public
([`ce386e4`](ce386e4c20))
- Updated string translations
([`198e08c`](198e08cf5e))
-   `SideSheet`
- Moved the modal side sheet default width/height into style so they can
be customized
- Updated string translations
([`198e08c`](198e08cf5e))
-   `Slider`
- Made tick size defaults to the stop indicator size if set
([`92bc02c`](92bc02c37c))
- Fixed incorrect style of stop indicators near handles
([`d61cffd`](d61cffd7eb))
- Resolved issues that crash when assigning a large value to `valueTo`
([`4d1b9e5`](4d1b9e58a5))
- Updated the track drawing for some corner cases.
([`10484df`](10484df407))
- Fixed ripple not transparent on API 33
([`cd4f618`](cd4f618d38))
- Updated documentation
([`a641e18`](a641e18b6a))
- Updated styles
([`c218b3c`](3b278d7097))
- Fixed slider label not moving while scrolling
([`144b515`](144b5159ce))
-   `Tabs`
- Fixed title being announced twice when there's a badge in TalkBack
mode.
([`aaa7034`](aaa7034cbf))
-   `Theming`
- Add NoActionBar dynamic color themes
([`81d1b77`](81d1b772b9))
- Update Shape Theming bottom sheet text color
([`8ca016f`](8ca016fb01))
-   `Tokens`
- Update tokens to v4.0.0.
([`88acfcd`](88acfcdb63))
- Added formatting to break long lines and differentiate different
comments.
([`857d6a2`](857d6a2fd9))
-   `TopAppBar`
- Use an accessibility delegate to add and perform actions
([`929c80f`](929c80f753))
- Fixed compress effect clipping on API 21-24
([`2ac8c1c`](2ac8c1cbf6))
-   `TextInputLayout`
- Limited the min height reset in text change listener only when line
count changes.
([`9b9449c`](9b9449cde1))
- Fixed unnecessary min height when losing focus with multiple lines.
([`4a2654a`](4a2654a3f3))
-   `Transitions / Motion`
- Updated androidx transition dep to version 1.5.0-beta01
([`8c63848`](8c63848829))
- Added predictive fade through fragment transition demo to Catalog.
([`6092a7d`](6092a7dfe9))
- Added titles to fade through demo fragments in Catalog.
([`104043c`](104043caee))
- Added predictive transition support for fragments and views to the
Material motion library, and enabled it in shared axis fragment
transition demo.
([`8ccec33`](8ccec334bd))

#### Full list of release notes

-
[1.12.0-alpha01](https://togithub.com/material-components/material-components-android/releases/tag/1.12.0-alpha01)
-
[1.12.0-alpha02](https://togithub.com/material-components/material-components-android/releases/tag/1.12.0-alpha02)
-
[1.12.0-alpha03](https://togithub.com/material-components/material-components-android/releases/tag/1.12.0-alpha03)
-
[1.12.0-beta01](https://togithub.com/material-components/material-components-android/releases/tag/1.12.0-beta01)
-
[1.12.0-rc01](https://togithub.com/material-components/material-components-android/releases/tag/1.12.0-rc01)

#### Full list of changes

</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 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:eyJjcmVhdGVkSW5WZXIiOiIzNy4zNTEuMiIsInVwZGF0ZWRJblZlciI6IjM3LjQxMC4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Nik Clayton <nik@ngo.org.uk>
2024-06-18 18:40:45 +02:00
renovate[bot] 882103893a
fix(deps): update dependency org.robolectric:robolectric to v4.12.2 (#707)
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [org.robolectric:robolectric](http://robolectric.org)
([source](https://togithub.com/robolectric/robolectric)) | `4.12.1` ->
`4.12.2` |
[![age](https://developer.mend.io/api/mc/badges/age/maven/org.robolectric:robolectric/4.12.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/maven/org.robolectric:robolectric/4.12.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/maven/org.robolectric:robolectric/4.12.1/4.12.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/org.robolectric:robolectric/4.12.1/4.12.2?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

> [!WARNING]
> Some dependencies could not be looked up. Check the Dependency
Dashboard for more information.

---

### 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:eyJjcmVhdGVkSW5WZXIiOiIzNy4zNjguMTAiLCJ1cGRhdGVkSW5WZXIiOiIzNy4zNjguMTAiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbXX0=-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Nik Clayton <nik@ngo.org.uk>
2024-06-18 14:30:17 +02:00
Nik Clayton 1468936970
chore(deps): update agp to v8.5.0, lint to 31.5.0 (#756)
New lint checks mean:

- Some trivial uses of String.format() are replaced with templates
- Use a string resource for the scheduled date and time

Some reported SetTextI18n warnings have been ignored, as they relate to
e.g., clearing a view's text by setting it to "".
2024-06-18 13:58:37 +02:00
Nik Clayton 3d5c2dd32f
feat: Show "Suggested accounts" (#734)
Implement suggestions as a new `feature:suggestions` module, with
associated activity, fragment, etc.

Suggested accounts are shown with their normal information, as well as
information about the number of follows / followers, and a guide to
posting frequency, so the user can make a more informed decision about
whether to follow or not.
2024-06-17 21:43:12 +02:00
Nik Clayton 00a88c7874
refactor: Allow PachliError.formatArgs to be null (#755)
Simplifies the case where there are no format args.
2024-06-17 21:29:22 +02:00
Nik Clayton 2327ab5221
refactor: Move actions.xml to core.ui (#754) 2024-06-17 20:38:19 +02:00
Nik Clayton 3a1a0073e9
refactor: Move action_{links,mentions,hashtags}, title_{hashtags,links}_dialog strings to core.ui (#753)
Moving ahead of Suggestions work to minimise diffs.
2024-06-17 20:21:53 +02:00
Nik Clayton d8d15ab5b0
change: Simplify mapBoth operations to mapEither and map (#746) 2024-06-13 22:55:16 +02:00
Weblate (bot) 6d266bce6d
fix(l10n): Translations update from Hosted Weblate (#737)
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/Core/Data :
Main](https://hosted.weblate.org/projects/pachli/coredata-main/)

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

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

* [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/Feature/About :
Main](https://hosted.weblate.org/projects/pachli/featureabout-main/)

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

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

* [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: Languages add-on <noreply-addon-languages@weblate.org>
2024-06-13 22:54:02 +02:00
Nik Clayton dd0e01a15c
refactor: Move IconUtils to core.ui (#744) 2024-06-13 21:34:49 +02:00
Nik Clayton 892663cab3
refactor: Move ReselectableFragment to core.activity (#743) 2024-06-13 21:16:10 +02:00
Nik Clayton 3b5d7d3f2d
fix: Disable BackgroundMessageView button when it's clicked (#742) 2024-06-13 21:12:11 +02:00
Nik Clayton efd1c8e556
refactor: Use the PachliError type for ApiError (#739)
In the previous code `PachliError` could correctly chain errors and
generate error messages, `ApiError` didn't, which is why there was the
temporary `ApiError.fmt()` extension function.

Rewrite `ApiError` to implement `PachliError` so it gets these benefits
and to reduce the number of different error-handling mechanisms in the
code.

Main changes:

- `PachliError` is now an interface so it can be extended by other
  error interfaces.
- All the `ApiError` subclasses implement `PachliError`, and can
  specify the error string and interpolated variables at the point of
  declaration.
- Update `ListsRepository` and `ServerRepository` to return
  `PachliError` subclasses.
2024-06-12 10:22:27 +02:00
Nik Clayton d0432dbd24
refactor: Move string post_username_format to core.designsystem (#736) 2024-06-10 21:06:31 +02:00
Nik Clayton 9f4652c6cf
refactor: Move LinkHelper and AsciiFolding to core.ui (#735) 2024-06-10 20:38:16 +02:00
Nik Clayton 7cf7476c49
refactor: Move throttleFirst to core.common (#733) 2024-06-10 19:57:47 +02:00
Nik Clayton 46c7307c0d
refactor: Move LinkListener to core.ui (#732) 2024-06-10 17:40:23 +02:00
Nik Clayton a68e1bf63b
refactor: Move StatusDisplayOptions and Repository to core.data (#731) 2024-06-10 17:29:09 +02:00
Nik Clayton dc61030b98
refactor: Move AccountPreferenceDataStore to core.data (#730) 2024-06-10 16:54:14 +02:00
Nik Clayton 5dd1b9a2f9
refactor: Move CardViewMode to core.preferences (#729) 2024-06-10 16:28:55 +02:00
Nik Clayton e4a065ca9f
refactor: Move ServerRepository to core.data (#728) 2024-06-10 16:08:48 +02:00
Nik Clayton c5fe30088d
chore(deps): update kotlin to v2 (major) (#725) 2024-06-05 15:15:56 +02:00
Nik Clayton 4520a29c74
fix: Generate useful error messages for all errors (#719)
Previous code was inconsistent about using getServerErrorMessage() and
whether or not the case where getServerErrorMessage() returns null was
handled.

Switch to using getErrorString() which does handle the null case and
always returns a usable string.

Some string resources are rendered temporarily unused by this change.
They will be used again soon, so configure lint to ignore them at the
moment.
2024-05-30 19:14:43 +02:00
Nik Clayton 51c4469e85
feat: Check Hometown/Glitch server instanceinfo for translation support (#718)
Previous code only looked for translation support on Mastodon servers.
It may be present on Hometown/Glitch servers too, so check.

Fixes #714
2024-05-30 19:14:27 +02:00
Nik Clayton 84fdf4abb7
fix: Only include transitionKind in intents for Pachli activities (#716)
Previous code always included the transitionKind enum as an extra, and
could cause a crash if the activity launched by the intent was not a
Pachli activity.

Fixes #700.
2024-05-30 14:05:42 +02:00
Miles Krell ee8f2b69b8
remove: remove janky animation warning (#658)
This warning (added in #274) includes a comment saying that we can
remove it after 2024-03-01, so the time has come :)
2024-04-30 16:25:05 +02:00
Nik Clayton 45b7e8777f change: Use SAM with `sortWith` comparator 2024-04-30 16:23:34 +02:00
Nik Clayton 3c9dd8655d change: `!x.isEmpty()` -> `x.isNotEmpty()` 2024-04-30 16:23:34 +02:00
Nik Clayton 56b0505955 change: Remove obsolete @Suppress annotations 2024-04-30 16:23:34 +02:00
Nik Clayton 1f50a9cbe7 change: Remove unnecessary types 2024-04-30 16:23:34 +02:00
Nik Clayton 01887d427b change: Remove unnecessary `constructor` keyword 2024-04-30 16:23:34 +02:00
Nik Clayton 286a152fde change: Move MediaUploadApi to the correct package 2024-04-30 16:23:34 +02:00
Nik Clayton 2d0cf6c17e change: Mark some properties private 2024-04-30 16:23:34 +02:00
Nik Clayton 2236f53838
fix: Show edit history for status' with polls (#672)
Edited polls only include the list of options with titles; no other
metadata (poll ID, single/multiple choice, vote counts, etc). Since the
data shape didn't match Moshi wasn't decoding the data.

Provide dedicated data classes to model the response, and add a fourth
poll display option to represent viewing an edit history snapshot.
2024-04-30 14:38:36 +02:00
Nik Clayton 362cdfeb27
fix: Prevent crash when Pachli is a share target (#659)
Crash was occuring because the instance info hadn't been fetched, trying
to take the last item of an empty list.

To fix:

- Expose the instance info as a state flow, with a default. New instance
info is fetched whenever the active account changes.

- Do the same for the emojis supported by the server.

- Update call sites as appropriate.

- Mark `InstanceInfoRepository` as `@Singleton` so it isn't repeatedly
created causing fresh content fetches.

The tests needed updating to get this to work.

- Extract the network fake modules in to a network-test module so
multiple other modules can use them.

- Rewrite `InstanceInfoRepositoryTest` to use Hilt and use Turbine to
test the new flows.

Checking this showed cosmetic bugs in the About layout when instance
info is missing, clean those up.
2024-04-28 18:19:13 +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 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 d4105ecf2f fix(l10n): Update Spanish translations
Currently translated at 100.0% (12 of 12 strings)

Translation: Pachli/Core/Ui : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/coreui-main/es/
2024-04-23 22:25:56 +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 cc9efbfa7a
ci: Simplify and improve CI speed (#615)
Abstract common CI setup tasks (setting up Java, Gradle, etc) in to a
single action that can be used by all CI workflows.

Run the lint, test, and assemble CI tasks in parallel for each variant
rather than in series, which cuts ~ 7 minutes (approx. 50%) off the CI
runtime.

Update code in checks and core/navigation to fix new tests.
2024-04-15 15:24:07 +02:00
Nik Clayton dd2efe9795
feat: Disable filters for accounts on servers running Sharkey (#610)
Fixes #600.
2024-04-09 16:23:04 +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
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 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 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 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 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
Nik Clayton 783d4e5cca
feat: Notify the user about severed relationships (#557) 2024-03-21 17:27:48 +01:00
Nik Clayton 4f9b283432
refactor: Simplify and optimize viewBinding delegate (#544)
Based on Christophe Beyl's technique described in

https://bladecoder.medium.com/viewlifecyclelazy-and-other-ways-to-avoid-view-memory-leaks-in-android-fragments-4aa982e6e579
2024-03-19 16:42:08 +01:00
ButterflyOfFire b478f38e19 fix(l10n): Update Kabyle translations
Currently translated at 72.7% (8 of 11 strings)

Translation: Pachli/Core/Ui : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/coreui-main/kab/
2024-03-18 19:31:42 +01:00
Weblate (bot) f64f9f03ae
fix(l10n): Translations update from Hosted Weblate (#541)
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/Core/Ui :
Main](https://hosted.weblate.org/projects/pachli/coreui-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/)



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-03-17 00:24:12 +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 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 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 e93e4ffb53
feat: Support client filters in GoToSocial 0.15.0 (#523) 2024-03-11 23:14:57 +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
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
sanao 0105a8179c
test: close DB in TimelineDaoTest (#512)
The previous code forgot to close the DB after TimelineDaoTest was run,
so a warning message was displayed when the test was run locally.

Close the database using the `@After` annotation.

Fixes #511
2024-03-08 11:40:51 +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 f9e2c7a47c fix(l10n): Update Spanish translations
Currently translated at 100.0% (4 of 4 strings)

Translation: Pachli/Core/Network : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/corenetwork-main/es/
2024-03-04 20:33:08 +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 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 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
Nik Clayton f5d90081ff
fix: Provide v2/instance configuration defaults (#474)
Some servers don't include a `urls` or `translation` block, which was
preventing parsing of the block, and falling back to the v1 instance
data.

Fix this by providing sensible defaults.
2024-02-26 17:21:33 +01:00
Martijn de Boer 6ca085089e fix(l10n): Update Dutch translations
Currently translated at 100.0% (4 of 4 strings)

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

Translation: Pachli/Core/Network : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/corenetwork-main/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 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 13cfa1a15d
fix: Remove filters from Firefish capabilities (#459)
Firefish doesn't support the filters API, so remove filters from the
list of capabilities.

Fixes #248
2024-02-20 14:41:48 +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
JuanM 55ee447bdb fix(l10n): Update Spanish translations
Currently translated at 100.0% (3 of 3 strings)

Translation: Pachli/Core/Activity : Orange
Translate-URL: https://hosted.weblate.org/projects/pachli/coreactivity-orange/es/
2024-02-17 10:01:04 +01:00
JuanM 086d6bc85e fix(l10n): Update Spanish translations
Currently translated at 100.0% (4 of 4 strings)

Translation: Pachli/Core/Activity : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/coreactivity-main/es/
2024-02-17 10:01:04 +01:00
JuanM 0f13db8fb2 fix(l10n): Update Spanish translations
Currently translated at 75.0% (3 of 4 strings)

Translation: Pachli/Core/Network : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/corenetwork-main/es/
2024-02-17 10:01:04 +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 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 6c33204569
fix: Prevent crashes with bugs in Friendica and Pleroma servers (#441)
Neither server type implements the Mastodon API correctly, see

- https://github.com/friendica/friendica/issues/13887
- https://git.pleroma.social/pleroma/pleroma/-/issues/3238

Prevent crashes when parsing their broken JSON by providing default
values for properties they omit.

Fixes #433
2024-02-14 12:36:06 +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 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 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ä 29538576d6 fix(l10n): Update Finnish translations
Currently translated at 100.0% (4 of 4 strings)

Translation: Pachli/Core/Activity : Main
Translate-URL: https://hosted.weblate.org/projects/pachli/coreactivity-main/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
ButterflyOfFire 93595a04d3 fix(l10n): Update Arabic translations
Currently translated at 66.6% (2 of 3 strings)

Translation: Pachli/Core/Activity : Orange
Translate-URL: https://hosted.weblate.org/projects/pachli/coreactivity-orange/ar/
2024-02-03 15:26:43 +01:00
Languages add-on c0303fb76c feat(l10n): Added Chinese (Simplified) (zh_MO) translation 2024-02-03 15:26:43 +01:00
Languages add-on 91a615e767 feat(l10n): Added Chinese (Simplified, Singapore) translation 2024-02-03 15:26:43 +01:00
Languages add-on a27787422b feat(l10n): Added Berber translation 2024-02-03 15:26:43 +01:00
Languages add-on 1a239d22c7 feat(l10n): Added Norwegian Bokmål translation 2024-02-03 15:26:43 +01:00
Languages add-on 4f19ec0e22 feat(l10n): Added Bengali (Bangladesh) translation 2024-02-03 15:26:43 +01:00
Languages add-on fcefb700ad feat(l10n): Added Sanskrit translation 2024-02-03 15:26:43 +01:00
Languages add-on 82248a86d8 feat(l10n): Added Kabyle translation 2024-02-03 15:26:43 +01:00
Languages add-on 66a96256c8 feat(l10n): Added Chinese (Simplified) translation 2024-02-03 15:26:43 +01:00
Languages add-on 8d5ee0056c feat(l10n): Added Chinese (Traditional) translation 2024-02-03 15:26:43 +01:00
Languages add-on e318c47887 feat(l10n): Added Kurdish (Central) translation 2024-02-03 15:26:43 +01:00
Languages add-on 248df881da feat(l10n): Added Portuguese (Portugal) translation 2024-02-03 15:26:43 +01:00
Languages add-on dbddd0a1c3 feat(l10n): Added Slovenian translation 2024-02-03 15:26:43 +01:00
Languages add-on 5aba014fce feat(l10n): Added Sinhala translation 2024-02-03 15:26:43 +01:00
Languages add-on ddaa2ef853 feat(l10n): Added Slovak translation 2024-02-03 15:26:43 +01:00
Languages add-on 1f9471afdd feat(l10n): Added Korean translation 2024-02-03 15:26:43 +01:00
Languages add-on a96e050314 feat(l10n): Added Persian translation 2024-02-03 15:26:43 +01:00
Languages add-on 11874d157b feat(l10n): Added Frisian translation 2024-02-03 15:26:43 +01:00
Languages add-on 2badc4bfaf feat(l10n): Added French translation 2024-02-03 15:26:43 +01:00
Languages add-on 66f1f6e7c9 feat(l10n): Added Spanish translation 2024-02-03 15:26:43 +01:00
Languages add-on 20c102df33 feat(l10n): Added Bengali (India) translation 2024-02-03 15:26:43 +01:00
Languages add-on 5bdbfba751 feat(l10n): Added Indonesian translation 2024-02-03 15:26:43 +01:00
Languages add-on 6a3540cead feat(l10n): Added Italian translation 2024-02-03 15:26:43 +01:00
Languages add-on 4a5a8c3075 feat(l10n): Added Polish translation 2024-02-03 15:26:43 +01:00
Languages add-on 43814b2b29 feat(l10n): Added Malayalam translation 2024-02-03 15:26:43 +01:00
Languages add-on e8a6066328 feat(l10n): Added Hebrew translation 2024-02-03 15:26:43 +01:00