The previous code only attempted to restore the user's reading position
once, after any initial refresh.
Adjust this so the position is restored after any refresh (which may
have been triggered from a menu instead of a swipe), and use
`scrollToPositionWithOffset` to ensure it's visible.
Testing showed additional activities with toolbar flicking issues. Fix
as before, using `setLiftOnScrollTargetView` to specify the scrolling
view the toolbar should lift above.
The chips for adding a new hashtag to a tab specified the background
colour without setting the text colour, resulting in the colour being
too low-contrast against the background.
Use `?colorOnPrimary` to get the correct colour.
Switching to the Material 3 themes caused the previous list dividers to
disappear.
Replace `DividerItemDecoration` with `MaterialDividerItemDecoration` to
restore them.
The previous code would always fetch the latest statuses when the app
restarts, jumping the user to the top of the home timeline. This is
because state.anchorPosition was null in this case.
Fix this by passing the saved initialKey to CachedTimelineRemoteMediator
and using it to construct a page of statuses around the requested
status.
This restores the user's reading position, and ensures that if the
user is at the top of the list their reading position is not reset
to the second item in the list.
Fixes#41, #42
The previous code did not handle refreshing correctly; it retained some
of the cache, and tried merge new statuses in to the cache. This does
not work, and resulted in the app creating gaps in the timeline if more
than a page's worth of statuses had appeared since the user last
refreshed (e.g., overnight).
Fix this by treating the on-device cache as disposable, as the Paging3
library intends. On refresh the cached timeline is emptied and replaced
with a fresh page.
This causes a problem for state that is not stored on the server but is
part of a status' viewdata (has the user toggled viewing a piece of
media, expanded a CW, etc).
The previous code tried to work around that by pulling the state out of
the page cache and copying it in to the new statuses. That won't work
when the page cache is being destroyed.
So do it properly -- store the viewdata state in a separate (sparse)
table that contains only rows for statuses that have a non-default
state.
Save changes to the state when the user interacts with a status, and
use the state to ensure that the viewdata for a status in a thread
matches the viewdata for the same status if it is shown on the home
timeline (and vice-versa).
Fixes#16
The previous code didn't collect the uiState, so it was fixed at the
default value, ignoring any changes that happened over the life of
the viewmodel.
Fix that, so that the FAB will hide/show on scroll according to the
user's preferences.
While I'm here simplify the show/hide logic. The previous code would
ignore the user's preference if scrolling up. There doesn't seem to
be a good reason for that, and spelunking 6+ years back through the
history didn't find a justification for that behaviour in the original
commit.
Fixes#15
Scrolling a thread, set of search results, or viewing a thread would
cause the toolbar to flicker as items moved under it.
Fix this by configuring the toolbar to `liftOnScroll` in the relevant
layouts.
It needs to be configured with the view (or ID of the view) that it
will be scrolling. For views that are in the same layout this is done
with the `liftOnScrollTargetViewId` attribute.
For views that are in different layouts (e.g. the toolbar is in
the activity and the scrolling view is in a fragment) the app bar's
`setLiftOnScrollTargetView` method must be called.
Do this in `TimelineFragment` if the hosting activity is a new
interface `AppBarLayoutHost`. Implement this interface in
`StatusListActivity`.
Update the relevant layouts to use `MaterialToolbar`.
Fixes#21
First crash appeared to be caused by a failure to find the
`attr/colorBackgroundAccent` colour from the theme.
It wasn't clear why the attribute could not be found, so to fix it was
simpler to remove the color and attribute entirely, and replace it with
something more appropriate from the Material 3 tokens.
- Preview cards are stroked with `colorOutline`
- Poll options use `colorPrimary` (user's vote) or `colorSecondary`
(other choices) with appropriate text colours.
- Links in link preview cards use `android:attr/textColorLink`
- The placeholder icon in preview cards uses `?android/textColorLink`
- Remove it from `help_message_background`, and stroke with
`?colorOutline`
Doing this I discovered several places where a colour was being
specified unnecessarily, those have been removed.
To make it easier to understand the theme hierarchy that has been
collapsed and renamed to follow Android conventions.
- AppTheme -> Base.Theme.Pachli
- BaseTheme -> Theme.Pachli
- DefaultTheme has been removed as unnecessary
This unearthed a second crash, where `attr/actionBarSizeWithSubtitle`
was not found.
To fix that create an explicit style for toolbars that need it, and
apply the style (`Pachli.Widget.Toolbar`).
This also surfaced a third problem, where the `fragment_timeline*`
layouts had not been updated in `layout-sw640dp`, so those have been
updated to reflect the same views/IDs as the default `fragment_timeline`
layout.
These changes caused a small chain of "unused resource" lint errors,
which have been fixed by removing the unused colours.
The Android Material libraries were also being implicitly depended on
through other library imports instead of being explicit. So include
them as an explicit dependency.
Fixes#18
Update missing or incorrect information in README.md
- Link to Weblate with a badge
- Link to Play and F-Droid stores
- Correct the link to the list of releases
- Link to CONTRIBUTING.md
Fixes#13
Instead of a single `CONTRIBUTING.md`, create an initial set of more
detailed documentation for the different types of contribution.
Start with `code.md` and `translate.md`, the processes for submitting
code and translations respectively.
Commit to documenting how to contribute documentation, project
management, user support, and social presence in the next week.
Ensure that project decisions are clear and transparent to potential
contributors by documenting them in `docs/decisions`, starting with
the decision to use conventional commits.
Use the MADR format (https://adr.github.io/madr/).
The previous code was operating on the wrong text, resulting in normal
URL spans (which have an underline) being applied, instead of the
correct spans (which don't).
Fix this by using the correct length.
Previous code created hashtag filters without the `#`, so muting the
tag `#something` would filter all posts that contained `something`,
with or without the `#`.
Fix this when creating filters, and only remove filters (when unmuting)
if the title and contents match.
Show a snackbar when hashtags are successfully muted/unmuted, so the
user is aware something happened.
While drafting the policy I noticed that the `READ_MEDIA_*` permissions
could be added (for newer devices), the `ACCESS_NETWORK_STATE`
permission was missing, and `VIBRATE` was unnecessary.
- Rename packages to app.pachli.*
- Switch to Pachli icons (blue / orange)
- Reset database schema version to 1
- Reset versionCode to 1 and versionName to "1.0"
- Update colour scheme, use colorPrimary etc through the app
- Use Material UI components for toolbars
- Use "Pachli" in strings (UI, constants, etc)
- Update copyright on code I contributed
- Update README
- Update fastlane metadata
Requiring trailing commas on multi-line lists of items (declarations
and call sites) reduces future repository churn when those lines are
changed, but introduces additional churn now.
Bite the bullet and make the change, as well as adjusting lines that
were too long / indented incorrectly.
The changes were performed automatically, using the `ktlintFormat` task.
Based on https://github.com/tuskyapp/Tusky/pull/3968 by
https://github.com/tinsukE
Filters that the user had set for the notifications timeline were not
being applied.
Fix this in NotificationsViewModel; fetch the user's filters and apply
them against the status in a notification. If the status should be
hidden it is removed, and if it should show a warning it does so.
The user can click through the warning to show the status.
Prior to this change the user had to repeatedly tap "Load more" when
scrolling. This is tedious for the user.
In addition, the previous code had bugs that meant that not all statuses
were being loaded. Users could leave the app for a while (overnight,
say), and when returning would discover far fewer statuses than had
actually been posted.
Fix this, following the architecture first introduced for notifications
(Fragment -> ViewModel -> Repository -> Source/Mediator).
- Load statuses for cached and non-cached timelines using Paging3
- Show Failures during a load, and the user can retry
- Delete the "Reading order" preference, it is no longer necessary
Android's choices for font customisation can be limited, depending on
the vendor. Allow users to choose from a small collection of embedded
fonts, chosen by asking users for recommendations.
The font choice is implemented as a preference. Provide a custom dialog
that shows the fonts (in that font) so the user can see what they're
choosing between.
Ensure the font's license information is displayed in the "About"
section.
The previous code did not credit all third party code used in the app,
or provide access to the licenses.
Fix this by adopting the "aboutlibraries" library, which processes
dependencies at build time and generates a list of dependencies,
versions, and license information to display to the user.
Use this to also ensure that the non-source dependencies (artwork,
emoji) are given appropriate credit.
The existing language list is incomplete, sorted incorrectly and does
not use the correct language names.
Add a small tool that parses the resource directories that contain
string translations, determines the correct language name and sort
order, and updates the correct application resources so language
lists are displayed correctly.
- Remove the existing restriction on the number of tabs
- Allow the tabs to scroll to display more
- Update UI and text resources to remove obsolete content
- Implement the trending posts API
- Display trending statuses as a new Timeline kind
- Allow the user to add trending statuses to a dedicated tab
- Always show the "Trending" option in the navigation menu
- Implement the trending links API
- Provide a Fragment/ViewModel/Repository and Adapter/ViewHolder set
to display the content
- Show all trends (as a pageable fragment list) in TrendingActivity
- Allow the user to add trending links to a dedicated tab
- Always show the "Trending" option in the navigation menu
### Objective
* Prevent data loss when the user inadvertently hits back or wants to
leave the profile edition with unsaved changes.
### Description
* To limit the number of changes to the existing codebase, I merely
re-used the same method used by `save()` in the ViewModel to decide
whether to make a network request or simply return the profile as-is.
* ~A bit of code juggling around in the ViewModel and I was able to use
the logic for all the encoding of each profile field (Which is what the
ViewModel caches in memory).~ Thanks @Lakoja for improving this in the
VM.
* A couple of internal data classes used as helpers to move all the
fields around (now that they are no longer used in one single place)
were introduced.
### Potential Optimizations
* ~The profile encoding is done twice (once for checking, and then again
if the user has to actually save it). I'd say this is a negligible price
to pay, since the alternative would be to create a different set of
comparisons and/or keeping another profile in memory for the purpose of
comparison.~
### Visual Improvement
* I believe the Dialog is difficult to see, but it's being displayed
with Tusky's theme. Perhaps there's a better style to apply in this
case? (or maybe the edit profile activity shouldn't have the same
background color as dialogs?!)
### Issue
* #3486
Reverts tuskyapp/Tusky#3840. Turns out this needs to be enabled at
Bitrise, and it's not on our plan. So every build is running this extra
workflow, but it's not providing any benefit, just slowing things down.
Runs `ktlintFormat`, and adds comments to the PR if that generates any
diffs. The comments include the fix, which can be accepted immediately
through the GitHub UI.
Set the "System Design" as the default theme.
This ensures that the app's initial behaviour respect's the user's system-wide theme choice, while still allowing the user to adjust it later.
This is only done for new installs of Tusky. If the user is upgrading from a previous release and they did not have an explicit theme set then the dark theme is used, and the UX does not change.