Commit Graph

70 Commits

Author SHA1 Message Date
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 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 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
bittin1ddc447d824349b2 0c4d182b2b fix(l10n): Update Swedish 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/sv/
2024-02-03 15:26:43 +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
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 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 355244a8e2
refactor: Destructure maps for more idiomatic code (#388) 2024-01-26 12:32:45 +01:00
Nik Clayton 28afd2ed4d
feat: Add Firefish as a server with a Mastodon API (#381) 2024-01-25 00:58:15 +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 fa2da5ae18
fix: Show display name in timelines, not the username (#377)
Commit 993b7469 inadvertently broke this by removing the @SerializedName
annotation, so the user's display name was always null and the UI fell
back to showing the username.

Fixes #371
2024-01-23 16:59:36 +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 993b74691a
chore(deps): update plugin ktlint to v12.1.0 (#358) 2024-01-09 17:50:20 +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 2a7eda667b fix: Prevent crash if a preview card does not have an author 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 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