Address linkification on Android is pretty busted, and the docs
acknowledge it (see Linkify#MAP_ADDRESSES). Safest thing to do
at the moment is remove it. Looks like we may be able to get
better address linkification on API >= 28, but adding it will
be more involved.
Fixes#7730
Previously, we'd only show the attachment button when the user had
yet to enter any text. To add an attachment after text was entered,
you'd have to go to the three-dot menu. Now we just show a little
attach button in the text area.
I also took the opportunity to clean up other button paddings and
stuff in the compose area so things look better and react to text
sizes more predictably.
Added a new logger that persists logs for a longer duration to the
user's cache directory. Logs are encrypted. The new logs are sent
in addition to the user's logcat output.
For short messages in a cluster, the contact photo was sometimes taller
than the actual bubble, leading to extra weird space. So instead we use
a container to hold the width of the cell, and set the avatar to be GONE
instead of INVISIBLE.
The previous way we were getting the next/previous record didn't take into
consideration that some records aren't in the cursor -- some are in the
fastRecords map. We now use the proper position to get the next/previous
message.
Apparently onAnimationEnd is not a reliable event on some Android
versions, so I've moved to instead using a simple postDelayed() that is
the same length as the animation.
The media size traditionally determines the bubble size, but the author
could make it wider, which would lead to rendering issues. In the case
of media attachments (images, videos, and shared contacts), we restrict
the width of the author name. When there's a number+profile name combo,
we split the space 50/50 between the two.
In particular, there were many issues with drawing corners.
Unfortunately, there's no pretty way to get masking working on every
Android version, so we have to switch back to using custom backgrounds
and then using multiple masking methods depending on Android version.
Also, I had to remove attr references in drawables. They crash on 4.x.
Unfortunately, there's apps out there that trigger contact changes
very frequently. Because we listen to the system for contact
changes to tell us when to sync, that could result in us sending
an abundance of contact syncs to linked desktop instances.
This throttles contact sync requests using the following methodology:
- By default, throttle contact syncs to 6 hrs while the app is
backgrounded.
- If a sync is throttled in the background, we set a dirty flag and
will execute the sync the next time the app is foregrounded.
- Syncs explicitly requested by desktop are never throttled.
The directory we were previously saving backups to on the external SD
card is actually deleted upon app uninstall and/or clearing the app's
data. There's also no reliable way to write to the root of an external
SD card (that isn't comically inconvenient), so for now it's safer if we
just move back to getting the regular 'ol standard external storage
directory (which is likely internal storage, despite its name).
Fixes#7845
For self-sends, we were never marking attachments as uploaded. I made is
so that happens now, but to prevent it for showing for already-sent
messages, we also don't show controls for self-send conversations.
This particularly helps with the bug where people who were newly added
to a group wouldn't receive an expiration timer until the first message
was sent.
Previously, contact shares would be displayed as "Media Message". Now
it'll show the same as it does in a notification, namely
"{contact-emoji} {contact-name}".
Previously, we were running this job in PushSendJob#onCanceled().
However, with the new retry logic, this won't happen for 24 hours.
Instead, we now schedule the job in PushSendJob#onRetry().
Previously, we retried based on a count. Now we've added the ability to
keep retrying for a specified time, using exponential backoff to
throttle attempts.
We never properly registered the ExpirationListener, meaning we were
relying on the wait-notify loop of ExpirationManager to delete things.
This normally works, but fails when your phone goes to sleep. So I
properly registered the receiver, and then added a failsafe to re-run
the ExpirationManager if we're about to render an expired message.
Fixes#7906
We have to make some changes, and it's gotten to the point where
maintaining it as a separate library is more hassle than it's worth,
especially with Google releasing WorkManager as the preferred job
scheduling library.
Previously, because apostrophes were 'banned' characters, searching for
them wouldn't work. That meant you couldn't find words like "I'm". Now
we just replace the apostrophe with a space and things "just work"
because of the nature of SQLite tokenization and prefix queries.
Previously, we didn't support highlighting search results that had
tokens in the middle of the matches, which is a possibility with FTS.
Now we do more robust highlighting, as well as highlight matches in
phone numbers.
Previously, we made each full-text search query a single prefix query.
That means that the query "do c" would turn into "do c*". That means it
would match "do cat" but not "dog cat".
Now, we make each token a prefix query. So "do c" would turn into
"do* c*". That means it would match both "do cat" and "dog cat".
Previously, if a message disappeared while looking at it in the search
results, it'd still stick around. Now they'll disappear from the results
in real-time.
1) There was an issue where we wouldn't auto-download group syncs.
2) There was another issue where we didn't show the download controls
for messages you sent yourself.
Fixed#7920
There was an issue where we were backing up group receipts and attachments
that were for expiring messages (which are already excluded from the backup).
This commit excludes these items from the backup, and for backups made
before this change, this commit also deletes these invalid entries at
the end of the restore process.
We also do a little database migration to cleanup any bad state that may
have been imported in the past.
Turns out that there's some weird quasi-state when you come out of
airplane mode, that if you do an InetAdress lookup, it returns some
weird IPv6-looking garbage address. Going to retry in that scenario
instead of assuming an outage.
Previously, if an operation failed, we set the result to "null".
However, this was a mistake. Setting the result at all assumes success.
Instead, we need to set an exception so the ListenableFuture knows that
the operation failed.
A variety of improvements to the image editor, such as:
- New, fullscreen styling
- Smoother lines
- Better text and sticker handling
- Improved color picker with a history pallette
- New highlighter tool
Previously, SQLCipher's memory usage would grow indefinitely, up until
it hit the end of the cursor. We've now switched to a release where the
memory used by the cursor can be bounded.
If a user is upgrading to use the SQLCipher database (which happened
back in 4.16, so this only applies to relatively dormant users who are
just getting back into the app) and received a new "user X joind signal"
message, then it could screw up the migration. So we're just dropping
these notifications that happen in this narrow window.
The sticky header cache was keeping views across rotations, causing them
to render incorrectly afterwards. I added a method to invalidate the
header layouts after rotation.
Fixes#7890.
First, FTS index contents do not need to be exported. They will be recreated naturally.
Second, we can't export the secret FTS tables, or SQLite will think it's corrupted.
Fixed an issue where jumbomoji were not properly being rendered
when using system emoji. Also fixed an issue where the text
content wasn't properly being recalculated when the view is
resized.
Fixes#7875
1. Switch to using default text rendering if there's no emoji present in
the string.
2. Reduce redudant redraws by skipping of setText() calls for identical
strings.
Together, these two changes should reduce the vast majority of
flickering we see with EmojiTextView ellipsizing.