### 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
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.
dc9e9f2aeb
modifed the code that fetched the value of EXTRA_NOTIFICATION_TYPE in an
intent, to use getSerializable().
However, the value was being placed in to the intent using putString().
This caused an exception when trying to update the summary notification,
so it would never update.
```
java.lang.ClassCastException: java.lang.String cannot be cast to com.keylesspalace.tusky.entity.Notification$Type
at com.keylesspalace.tusky.components.notifications.NotificationHelper.updateSummaryNotifications(NotificationHelper.java:321)
at com.keylesspalace.tusky.components.notifications.NotificationFetcher.fetchAndShow(NotificationFetcher.kt:87)
at com.keylesspalace.tusky.components.notifications.NotificationFetcher$fetchAndShow$1.invokeSuspend(Unknown Source:14)
```
Fix this by placing the value in to the intent using putSerializable(),
to match how it will be fetched.
Previously the notification filter and clear actions were shown as
buttons in the UI, with a preference that determined whether they were
displayed.
Remove this preference, and display them as menu items.
- "Filter notifications" is shown as an icon, if possible
- "Clear notifications" is only ever shown as a menu item, to reduce the
chance the user inadvertently selects it
To ensure that the options menu appears correctly, remove the code that
creates a "fake" action bar, and adjust the layouts so that there are
three toolbars;
- mainToolbar -- displays the icons, and the current "location" (Home,
Notifications, etc)
- topNav -- displays the row of tabs at the top
- bottomNav -- displays the row of tabs at the bottom
Only one of them is set as the support action bar (depending on the
user's preferences). This provides the "show a logo" and "show the
options menu" functionality as standard, without needing to re-implement
as the previous code did.
The "trending" functionality will expand to include trending links and
posts. But at the moment the "Trending" references in the code are
exclusively to hashtags.
Rename "Trending" to "TrendingTags" or similar everywhere necessary in
order to prepare for this.
This includes a database migration, as the identifier for the "Trending
tags" tab in the account preferences was changed from "Trending" to
"TrendingTags". The migration updates the stored value if necessary.
Before, intent creation was scattered across multiple sites, with account switching logic in both `ComposeActivity` and `MainActivity`.
Now, intents are only created in `MainActivity` Companion, and account switching only occurs in `MainActivity`
Fixes#3695
Prevent users from accidentally deleting filters by prompting them to confirm.
Add an AlertDialog extension that converts AlertDialog callbacks to linear control flow.
Fixes#3736.
Currently translated at 100.0% (617 of 617 strings)
Translated using Weblate (Vietnamese)
Currently translated at 100.0% (617 of 617 strings)
Co-authored-by: Hồ Nhất Duy <mastoduy@gmail.com>
Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/vi/
Translation: Tusky/Tusky
Previously, the thread indicator would start at the top of the avatar
for the status at the start of the thread, and end at the top of the
avatar for the status at the end of the thread.
If these avatars were partially transparent the thread indicator could
either (a) poke out of the top of the avatar at the start of the thread,
(b) not properly connect with the avatar at the end of the thread, or
(c) both.
Partially fix this by making the divider start/stop in the middle of the
avatar. This assumes that this area will typically have opaque content,
even if some of the rest of the avatar is transparent. This is not
always true, but it's still better than the current behaviour.
Avatars that are semi-transparent are a problem when viewing a thread,
as the line that connects different statuses in the same thread is drawn
underneath the avatar and is visible.
Fix this with a CompositeWithOpaqueBackground Glide transformation that:
1. Extracts the alpha channel from the avatar image
2. Converts the alpha to a 1bpp mask
3. Draws that mask on a new bitmap, with the appropriate background
colour
4. Draws the original bitmap on top of that
So any partially transparent areas of the original image are drawn over
a solid background colour, so anything drawn under them will not appear.
If:
1. You're viewing an account's media tab
2. Some of the media was marked sensitivei
3. The `alwaysShowSensitiveMedia` setting was `true`
tapping on the image (once) would do nothing visible, because it was
treated as the "reveal sensitive media" tap. You had to tap on it a
second time to open it.
Fix this, by passing the preference value through to the relevant code.
---------
Co-authored-by: Tiga! <maxiinne@proton.me>
To determine the earliest day to show in the calendar, take the current
date/time, add the minimum scheduled seconds buffer (which may roll the
date/time over to the next day), and then clamp to the start of that
day. So it's either today (if the current time + minimum scheduled
seconds is less than midnight) or it's tomorrow.
When displaying the calendar work around a misfeature in Material Date
Picker. It accepts UTC seconds-since-epoch, but does not convert it to
the local time for display.
While I'm here, show the selected day in the time picker's title.
Fixes https://github.com/tuskyapp/Tusky/issues/3916