Commit graph

1,924 commits

Author SHA1 Message Date
Levi Bard
7bc40b4b03
Fix comparison of nonnormalized latin tags (#4845)
Mastodon "normalizes" tag text for latin characters when storing tag
names, so the hashtag object it sends for `#Über` has the name `uber`.
With the new trailing hashtag bar, this was causing nonascii hashtags
from the post content to be duplicated with their normalized versions,
e.g. `#Über #uber`.

This change ensures that we're always comparing normalized tag names.
2025-01-04 19:13:52 +01:00
Konrad Pozniak
67800634a2
guard against invalid position in StatusNotificationViewHolder (#4844)
We do this in other ViewHolders as well

Seen in this crash report on Google Play:

```
Exception java.lang.IndexOutOfBoundsException: Index: -1, Size: 0
  at androidx.paging.PageStore.checkIndex (PageStore.kt:56)
  at androidx.paging.PageStore.get (PageStore.kt:66)
  at androidx.paging.PagingDataPresenter.peek (PagingDataPresenter.java:290)
  at androidx.paging.AsyncPagingDataDiffer.peek (AsyncPagingDataDiffer.java:476)
  at androidx.paging.PagingDataAdapter.peek (PagingDataAdapter.kt:312)
  at com.keylesspalace.tusky.components.notifications.NotificationsFragment.onViewThread (NotificationsFragment.kt:409)
  at com.keylesspalace.tusky.components.notifications.StatusNotificationViewHolder.bind$lambda$0 (StatusNotificationViewHolder.java:104)
  at android.view.View.performClick (View.java:7684)
  at android.view.View.performClickInternal (View.java:7661)
  at android.view.View.-$$Nest$mperformClickInternal (Unknown Source)
  at android.view.View$PerformClick.run (View.java:30344)
  at android.os.Handler.handleCallback (Handler.java:1000)
  at android.os.Handler.dispatchMessage (Handler.java:104)
  at android.os.Looper.loopOnce (Looper.java:242)
  at android.os.Looper.loop (Looper.java:362)
  at android.app.ActivityThread.main (ActivityThread.java:8393)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:552)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:992)
```
2025-01-04 18:44:34 +01:00
Konrad Pozniak
560411c5d0
hide trailing hashtags when post is collapsed (#4839)
closes https://github.com/tuskyapp/Tusky/issues/4838
2024-12-31 09:55:30 +01:00
Konrad Pozniak
f9fbf5de0c
improve CaptionDialog for small screens (#4831)
(or giant soft keyboards)

https://mastodon.social/@bewitchedmind/113703199056088283

Before / After

<img
src="https://github.com/user-attachments/assets/04d9f9b8-1041-4b1e-bff4-3665865a6016"
width="300"/>
<img
src="https://github.com/user-attachments/assets/f88bb67e-ecb0-460a-b22b-58cff5a4b754"
width="300"/>


This makes it also look a bit weird on large screens, but I found no
easy way to limit the size. Its now basically back to where it was in
Tusky 26.

closes https://github.com/tuskyapp/Tusky/issues/4832
2024-12-27 09:05:04 +01:00
Konrad Pozniak
20cb3848ee
fix "delete all notifications by user" query (#4821)
The brackets were at the wrong position and notification types are
actually serialized differently.

Closes #4817
2024-12-21 20:35:21 +01:00
Konrad Pozniak
dee1767ec1
fix MainActivity behavior (#4818)
This fixes two issues, but I tested them together to make sure this time
everything works as expected.

1) The fix in #4813 went into the right direction, but the condition was
a bit too broad. When sharing something to Tusky so that Tusky switches
accounts, sometimes nothing would happen.

2) fixes #4766. There are two possibilities here (I think it depends
mostly on API level):
2a) Sharing starts a new task. `android:maxRecents="1"` makes sure old
tasks disappear and are not left in the weird in-between state.
3a) Sharing starts a new `MainActivity` in an existing task.
`Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK` makes
sure old `MainActivity` instances are removed. On newer Android versions
this has the sideeffect of changing the switch animation, but whatever.

Basically this gives us the behavior I wanted to achieve with the
`android:launchMode="singleTask"` without the unintended side effects.
2024-12-21 20:34:54 +01:00
Konrad Pozniak
3e6bfe8776
make sure MainActivity doesn't hide other activities when launcher icon is clicked again (#4813)
closes #4789 this time for real, hopefully, maybe

also set `alwaysRetainTaskState` for good measure

> `android:alwaysRetainTaskState`
Whether the state of the task that the activity is in is always
maintained by the system. `"true"` if it is, and `"false"` if the system
can reset the task to its initial state in certain situations. The
default value is `"false"`. This attribute is meaningful only for the
root activity of a task. It's ignored for all other activities.

> Normally, the system clears a task, removing all activities from the
stack above the root activity, in certain situations when the user
re-selects that task from the home screen. Typically, this is done if
the user hasn't visited the task for a certain amount of time, such as
30 minutes.

> However, when this attribute is `"true"`, users always return to the
task in its last state, regardless of how they get there. This is useful
in an application like a web browser where there is a lot of state, such
as multiple open tabs, that users don't want to lose.


https://developer.android.com/guide/topics/manifest/activity-element#always
2024-12-18 09:17:46 +01:00
Levi Bard
8937d0abf0
Don't repeat inline tags in the trailing hashtag bar (#4811) 2024-12-15 20:58:19 +01:00
Konrad Pozniak
ec3921d923
show the warning icon again when there is media without description (#4806)
Regression from the Material 3 redesign
2024-12-14 19:33:37 +01:00
Levi Bard
c8d8891a07
Preserve the case of hashtags from content when possible (#4802)
https://social.tchncs.de/@KazuShuSora/113621293051641672
2024-12-11 17:53:32 +01:00
Konrad Pozniak
328aca7031
fix caption dialog (#4799)
The Material 3 redesign seems to have broken the dialog when very small
images where used.
Also removes the weird background behind the context menu (seen in the
before screenshot)

Before / after:
<img
src="https://github.com/user-attachments/assets/c418125d-ef80-458f-9d94-fde428a2f59f"
width="280"/> <img
src="https://github.com/user-attachments/assets/b832b16d-0c18-4bf1-a263-de4fe0362854"
width="280"/>
2024-12-10 21:11:55 +01:00
Levi Bard
af5d10cd09
Simplify hashtag line checker to avoid infinite loop in android matcher (#4779)
https://masto.nyc/@GetMisch/113557332197065306 causes an infinite loop
in the native matcher with the original pattern, trying a different
approach
2024-12-04 17:08:05 +01:00
Konrad Pozniak
cd57352cbd
Notification policy (#4768)
This was so much work wow. I think it works pretty well and is the best
compromise between all the alternative we considered. Yes the
pull-to-refreh on the notifications works slightly different now when
the new bar is visible, but I don't think there is a way around that.

Things I plan to do later, i.e. not as part of this PR or release:
- Cache the notification policy summary for better offline behavior and
less view shifting when it loads
- try to reduce some of the code duplications that are now in there
- if there is user demand, add a "legacy mode" setting where this
feature is disabled even if the server would support it

closes #4331
closes #4550 as won't do
closes #4712 as won't do

<img
src="https://github.com/user-attachments/assets/de322d3c-3775-41e7-be57-28ab7fbaecdf"
width="240"/> <img
src="https://github.com/user-attachments/assets/1ce958a4-4f15-484c-a337-5ad93f36046c"
width="240"/> <img
src="https://github.com/user-attachments/assets/98b0482b-1c05-4c99-a371-f7f4d8a69abd"
width="240"/>
2024-12-03 18:46:50 +01:00
Konrad Pozniak
05b2a5d70c
fix crash when post is single line with hashtags (#4778)
```
java.lang.StringIndexOutOfBoundsException
     at android.text.SpannableStringBuilder.<init>(SpannableStringBuilder.java:63)
     at android.text.SpannableStringBuilder.subSequence(SpannableStringBuilder.java:1198)
     at com.keylesspalace.tusky.util.LinkHelper.setClickableText(LinkHelper.kt:99)
     at com.keylesspalace.tusky.adapter.StatusBaseViewHolder.setTextVisible(StatusBaseViewHolder.java:289)
     at com.keylesspalace.tusky.adapter.StatusBaseViewHolder.setSpoilerAndContent(StatusBaseViewHolder.java:244)
     at com.keylesspalace.tusky.adapter.StatusBaseViewHolder.setupWithStatus(StatusBaseViewHolder.java:820)
     at com.keylesspalace.tusky.adapter.StatusViewHolder.setupWithStatus(StatusViewHolder.java:91)
     at com.keylesspalace.tusky.components.timeline.TimelinePagingAdapter.bindViewHolder(TimelinePagingAdapter.kt:100)
     at com.keylesspalace.tusky.components.timeline.TimelinePagingAdapter.onBindViewHolder(TimelinePagingAdapter.kt:82)
     at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7847)
     at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6646)
     at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6917)
     at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:288)
     at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:345)
     at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:361)
     at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:368)
     at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:399)
     at android.os.Handler.handleCallback(Handler.java:959)
     at android.os.Handler.dispatchMessage(Handler.java:100)
     at android.os.Looper.loopOnce(Looper.java:232)
     at android.os.Looper.loop(Looper.java:317)
     at android.app.ActivityThread.main(ActivityThread.java:8705)
     at java.lang.reflect.Method.invoke(Native Method)
     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:886)
```
2024-11-29 17:10:06 +01:00
Konrad Pozniak
fc52074dcd
remove some unused code (#4776) 2024-11-28 19:15:54 +01:00
Konrad Pozniak
bc397e993d
fix deprecated resume call in AlertDialogExtensions (#4775) 2024-11-28 19:15:44 +01:00
Levi Bard
d3feca3a10
mastodon-web-like trailing hashtag bar (#4761)
Rationale: Since the mastodon web UI has started stripping "trailing"
hashtags from post content and shoving it into an ellipsized section at
the bottom of posts, the general hashtag : content ratio is rising.

This is an attempt at adopting a similar functionality for Tusky.

Before:

<img width="420" alt="Screenshot of a hashtag-heavy post on Tusky
nightly"
src="https://github.com/user-attachments/assets/09c286e8-6822-482a-904c-5cb3323ea0e1">


After:
![Screenshot of the same post on this
branch](https://github.com/user-attachments/assets/fa99964d-a057-4727-b9f0-1251a199d5f8)
2024-11-28 19:15:31 +01:00
Konrad Pozniak
e758321866
fix updating filter expiration to indefinite (#4743)
Before we would not send `expires_in` when "indefinite" was selected.
But that left the expiration at the value it was before. To actually set
it to indefinite we need to send `expires_in`, but leave it empty.
With a value class this was actually really nice to fix, the code now
self-documents what the special values mean.

Also fixes a regression from the Material 3 redesign where the filter
duration drop down would not get populated when creating a filter.

Found while working on https://github.com/tuskyapp/Tusky/pull/4742
2024-11-05 20:44:08 +01:00
Konrad Pozniak
0d34804359
never filter own posts (#4742)
This is to match Mastodon web behavior.

Also, make revealing filtered boosts in non-cached timelines work (can
only happen on user profiles, other timelines don't have boosts).

found thanks to this: https://tech.lgbt/@darkfox/113378644538792719
2024-11-05 20:43:52 +01:00
Konrad Pozniak
a56c14340e
fix link preview images (#4751)
Before (sometimes) vs after:

<img
src="https://github.com/user-attachments/assets/baeff1b8-c1ea-4102-bb4d-f8b2063d0972"
width="240"/> <img
src="https://github.com/user-attachments/assets/748618d3-4eaf-4428-8a7c-c1314d156f66"
width="240"/>

I'm not sure what is going on here, Glide is being weird sometimes and
this change fixes it.

Regression from https://github.com/tuskyapp/Tusky/pull/4738
2024-11-04 19:03:34 +01:00
Konrad Pozniak
d7bb46cd67
fix pinning boosted posts (#4740)
closes https://github.com/tuskyapp/Tusky/issues/4739
2024-10-28 21:27:21 +01:00
Konrad Pozniak
4eaa8877c1
fix crash when loading card images with unusual aspect ratio (#4738)
closes https://github.com/tuskyapp/Tusky/issues/4725

I checked with examples from https://github.com/tuskyapp/Tusky/pull/2743
and looks like nothing broke. Not sure why the `.dontTransform()` was
there. It prevents Glide from correctly sizing the image, leading to a
crash.

<details>
<summary>Stacktrace</summary>

```
java.lang.RuntimeException: Canvas: trying to draw too large(401361624bytes) bitmap.
    at android.graphics.RecordingCanvas.throwIfCannotDraw(RecordingCanvas.java:266)
    at android.graphics.BaseRecordingCanvas.drawBitmap(BaseRecordingCanvas.java:94)
    at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:549)
    at android.widget.ImageView.onDraw(ImageView.java:1446)
    at com.google.android.material.imageview.ShapeableImageView.onDraw(ShapeableImageView.java:188)
    at android.view.View.draw(View.java:23266)
    at android.view.View.updateDisplayListIfDirty(View.java:22133)
    at android.view.View.draw(View.java:22997)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
    at android.view.View.draw(View.java:23269)
    at android.view.View.updateDisplayListIfDirty(View.java:22133)
    at android.view.View.draw(View.java:22997)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
    at androidx.constraintlayout.widget.ConstraintLayout.dispatchDraw(ConstraintLayout.java:1994)
    at android.view.View.updateDisplayListIfDirty(View.java:22124)
    at android.view.View.draw(View.java:22997)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
    at androidx.recyclerview.widget.RecyclerView.drawChild(RecyclerView.java:5545)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
    at android.view.View.draw(View.java:23269)
    at androidx.recyclerview.widget.RecyclerView.draw(RecyclerView.java:4944)
    at android.view.View.updateDisplayListIfDirty(View.java:22133)
    at android.view.View.draw(View.java:22997)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
    at android.view.View.updateDisplayListIfDirty(View.java:22124)
    at android.view.View.draw(View.java:22997)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
    at android.view.View.draw(View.java:23269)
    at android.view.View.updateDisplayListIfDirty(View.java:22133)
    at android.view.View.draw(View.java:22997)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
    at android.view.View.updateDisplayListIfDirty(View.java:22124)
    at android.view.View.draw(View.java:22997)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
    at androidx.coordinatorlayout.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1277)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
    at android.view.View.updateDisplayListIfDirty(View.java:22124)
    at android.view.View.draw(View.java:22997)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
    at androidx.fragment.app.FragmentContainerView.drawChild(FragmentContainerView.kt:232)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
    at androidx.fragment.app.FragmentContainerView.dispatchDraw(FragmentContainerView.kt:222)
    at android.view.View.updateDisplayListIfDirty(View.java:22124)
    at android.view.View.draw(View.java:22997)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
    at androidx.coordinatorlayout.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1277)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
    at android.view.View.updateDisplayListIfDirty(View.java:22124)
    at android.view.View.draw(View.java:22997)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
    at android.view.View.updateDisplayListIfDirty(View.java:22124)
    at android.view.View.draw(View.java:22997)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
    at android.view.View.updateDisplayListIfDirty(View.java:22124)
    at android.view.View.draw(View.java:22997)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
    at android.view.View.updateDisplayListIfDirty(View.java:22124)
    at android.view.View.draw(View.java:22997)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
    at android.view.View.updateDisplayListIfDirty(View.java:22124)
    at android.view.View.draw(View.java:22997)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4529)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4290)
    at android.view.View.draw(View.java:23269)
    at com.android.internal.policy.DecorView.draw(DecorView.java:821)
    at android.view.View.updateDisplayListIfDirty(View.java:22133)
    at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:689)
    at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:695)
    at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:793)
    at android.view.ViewRootImpl.draw(ViewRootImpl.java:4789)
    at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:4500)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3687)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2371)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:9297)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1231)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239)
    at android.view.Choreographer.doCallbacks(Choreographer.java:899)
    at android.view.Choreographer.doFrame(Choreographer.java:832)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214)
    at android.os.Handler.handleCallback(Handler.java:942)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    at android.app.ActivityThread.main(ActivityThread.java:7924)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
```
</details>
2024-10-28 21:27:09 +01:00
Konrad Pozniak
f8cf38c81b
fix how emojis in link texts are displayed (#4723)
![Screenshot_20241010_204357](https://github.com/user-attachments/assets/6f511231-b89c-4902-ad89-68c1940415a7)

closes https://github.com/tuskyapp/Tusky/issues/4720
2024-10-11 11:25:43 +02:00
Konrad Pozniak
92f980be2a
allow setting descriptions on audio attachments (#4711) 2024-10-11 09:24:12 +02:00
Konrad Pozniak
c45a3320d2
don't spam endless posts when trying to schedule on GoToSocial (#4705)
closes #4703
2024-10-11 09:23:30 +02:00
Konrad Pozniak
20bd90faae
Material3 polishing (#4673)
see commit messages for a list of changes

closes #4692
2024-10-11 08:51:34 +02:00
Konrad Pozniak
2a4e785bd7
make browser login work again (#4704)
Yes, saving the data in the savedInstanceState is nicer... but
SharedPreferences works better so lets revert this code

closes #4702 
closes #4592
2024-10-09 16:19:11 +02:00
Konrad Pozniak
d00ad17603
remove wrong statuses attribute from Announcement model (#4699)
https://docs.joinmastodon.org/entities/Announcement/

The statuses in this model are not full statuses but we expect them, so
parsing a response that contains one fails.
`com.squareup.moshi.JsonDataException: Required value 'account' missing
at $[0].statuses[1]`

Since we don't even use the attribute, we can just remove it to fix the
bug.

Closes #4696
2024-09-28 07:43:18 +02:00
Konrad Pozniak
13a9e9eb37
fix crash in ViewImageFragment (#4686)
From Play console crash logs. Well, let's put another band aid on this
code....

```
Exception java.lang.IllegalStateException:
  at androidx.fragment.app.Fragment.requireActivity (Fragment.java:1005)
  at com.keylesspalace.tusky.fragment.ViewImageFragment.getPhotoActionsListener (ViewImageFragment.java:59)
  at com.keylesspalace.tusky.fragment.ViewImageFragment.access$getPhotoActionsListener (ViewImageFragment.java:49)
  at com.keylesspalace.tusky.fragment.ViewImageFragment$onViewCreated$singleTapDetector$1.onSingleTapConfirmed (ViewImageFragment.kt:116)
  at android.view.GestureDetector$GestureHandler.handleMessage (GestureDetector.java:379)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loopOnce (Looper.java:230)
  at android.os.Looper.loop (Looper.java:319)
  at android.app.ActivityThread.main (ActivityThread.java:8919)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:578)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1103)
```
2024-09-27 16:20:22 +02:00
Konrad Pozniak
c887c8213c
fix new warnings, regenerate lint-baseline.xml (#4684)
Mostly "StringFormatTrivial" which I think is new, but it makes totally
sense to fix
2024-09-16 20:57:27 +02:00
Konrad Pozniak
a98154101b
revert MainActivity launchMode again (#4685)
This fixes
- The problem where Tusky drops your draft when you switch apps while
composing
- The problem where MainActivity does not restart when switching theme
in preferences

This adds back a bug where one can have multiple instances of
MainActivity which can behave weirdly when the active account was
switched after they were created. This bug is (unlike the timeline mixup
one) transient though, it will go away when restarting the app. As a
small mitigation MainActivity is finished when forwarding to
ComposeActivity (Tusky 25 behavior).
2024-09-16 20:57:15 +02:00
Konrad Pozniak
f2a2c16464
Better refreshing state handling for AccountViewModel (#4680)
Closes #4353 by addressing the last edge case: The swipe to refresh
won't be enabled before something is loaded, preventing multiple loads
at the same time. After the first load, the swipe to refresh itself
prevents multiple loads: It can be swiped only once.

---------

Co-authored-by: Goooler <wangzongler@gmail.com>
2024-09-15 17:32:19 +02:00
Konrad Pozniak
b693d4d466
remove extra newlines on some PIxelfed posts (#4672)
closes https://github.com/tuskyapp/Tusky/issues/4663
2024-09-13 15:52:48 +02:00
Andrew Hamilton
3c25b76853
Adds auto keyboard popup to dialogs (#4667)
Adds auto keyboard popup to ListsActivity, FollowedTagsActivity,
EditFilterActivity, CaptionDialog, and AddPollDialog.kt, and
AddHashtagDialog in TabPreferenceActivity. These are all dialog screens
which editing texts are the main purposes

---------

Co-authored-by: Weblate <42475313+nailyk-weblate@users.noreply.github.com>
Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Danial Behzadi <dani.behzi@ubuntu.com>
Co-authored-by: Manuel <mannivuwiki@gmail.com>
Co-authored-by: Eric <ekhfcxwuvxqfdb@hldrive.com>
Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com>
2024-09-13 15:52:11 +02:00
Konrad Pozniak
50ca44a5f6
Material Design 3 (#4637)
I tried to find a balance between going fully M3 and keeping some of the
original Tusky feeling.
For example, I removed the "allCaps" setting we had on most buttons,
which is recommended for M3. On the other hand, I made them less rounded
than the M3 default.

<img
src="https://github.com/user-attachments/assets/9d2485e0-7d1d-42ab-8a4e-c30d044aa5dc"
width="320"/>
<img
src="https://github.com/user-attachments/assets/d65d3c91-afe9-424e-92d7-e0f3e401ea4b"
width="320"/>
<img
src="https://github.com/user-attachments/assets/d5634440-c507-4484-a11e-983f47cbeab7"
width="320"/>
2024-09-10 19:50:09 +02:00
Konrad Pozniak
a9d6b60291
continue uploading media after sending post (#4662)
regression from https://github.com/tuskyapp/Tusky/pull/4599

https://pug.ninja/@motoridersd/113102603349423738

The problem is, `MediaUploader` is no longer a singleton, so the state
is not correctly shared between `ComposeActivity` and
`SendStatusService.` But it can't be a singleton, since `MediaUploadApi`
(injected into `MediaUploader`) needs to be recreated on account change.
Let's share the state in the companion object instead.
2024-09-10 19:16:53 +02:00
Konrad Pozniak
4f135c7f7b
fix hidden url markup when link text contains 🔗 (#4650)
Found a post that had a link that contained a 🔗 in the link text, which
tripped up our algorithm.
https://toot.mirbsd.org/@fefes_blog/statuses/01J6YVRNW9C3Q6GBCWKT96CYD0

Before / After

<img
src="https://github.com/user-attachments/assets/b2ce6f0c-7ae2-4351-86f9-2564252e9a62"
width="280"/>
<img
src="https://github.com/user-attachments/assets/589ffe6d-e57e-4c2e-bd82-b01ef178d551"
width="280"/>
2024-09-09 18:18:00 +02:00
andrewhamilton0
60a1922db6
This allows user to translate own post (#4648)
This allows user to translate own post
Closes #4645
2024-09-04 21:35:27 +02:00
mcclure
2a1cc7580c
Do not cancel the caption dialog on touches on navbar (#4643)
This one is odd.
I find that if I
- Add an image to a post
- Set a caption on the image
- Tap the caption dialog to bring up the keyboard
- Tap the navbar (very easy to do by accident while typing, just tap
under the spacebar)

The caption dialog disappears and you lose your caption.
(This doesn't happen in ANY other dialog in the app, and in the caption
dialog it ONLY happens when the keyboard is up.)
I got a tablet and on the tablet this happens ALL THE TIME.

I was considering adding a "really cancel?" dialog to the caption
dialog. But then I discovered (thank you @memorion@mastodon.social) by
setting getCanceledOnTouchOutside(false), I could make the bad behavior
go ahead completely. In my tests now I can only make the dialog go away
by tapping the actual back button.

I believe the potential negative impact of this is low because the
caption dialog is full screen, so it was already impossible to trigger
the touch outside behavior on *purpose*.

I might attempt a "really cancel caption?" dialog later because it sucks
to lose a long caption you have typed, but I think this fixes my
personal problem by itself.

---------

Co-authored-by: Konrad Pozniak <connyduck@users.noreply.github.com>
2024-09-02 20:50:55 +02:00
Konrad Pozniak
24f227fd4f
fix crash when there are reblogs in notification statuses (#4638)
```
android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)
    at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
    at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:961)
    at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:790)
    at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:89)
    at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.kt:42)
    at androidx.room.EntityInsertionAdapter.insertAndReturnId(EntityInsertionAdapter.kt:101)
    at com.keylesspalace.tusky.db.dao.TimelineStatusDao_Impl$insert$2.call(TimelineStatusDao_Impl.kt:345)
    at com.keylesspalace.tusky.db.dao.TimelineStatusDao_Impl$insert$2.call(TimelineStatusDao_Impl.kt:340)
    at androidx.room.CoroutinesRoom$Companion.execute(CoroutinesRoom.kt:56)
    at com.keylesspalace.tusky.db.dao.TimelineStatusDao_Impl.insert(TimelineStatusDao_Impl.kt:340)
    at com.keylesspalace.tusky.components.notifications.NotificationsRemoteMediator.replaceNotificationRange(NotificationsRemoteMediator.kt:169)
    at com.keylesspalace.tusky.components.notifications.NotificationsRemoteMediator.access$replaceNotificationRange(NotificationsRemoteMediator.kt:36)
    at com.keylesspalace.tusky.components.notifications.NotificationsRemoteMediator$load$3.invokeSuspend(NotificationsRemoteMediator.kt:109)
    at com.keylesspalace.tusky.components.notifications.NotificationsRemoteMediator$load$3.invoke(Unknown Source:8)
    at com.keylesspalace.tusky.components.notifications.NotificationsRemoteMediator$load$3.invoke(Unknown Source:2)
    at androidx.room.RoomDatabaseKt$withTransaction$transactionBlock$1.invokeSuspend(RoomDatabaseExt.kt:62)
    at androidx.room.RoomDatabaseKt$withTransaction$transactionBlock$1.invoke(Unknown Source:8)
    at androidx.room.RoomDatabaseKt$withTransaction$transactionBlock$1.invoke(Unknown Source:4)
    at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:61)
    at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:163)
    at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)
    at androidx.room.RoomDatabaseKt$startTransactionCoroutine$2$1$1.invokeSuspend(RoomDatabaseExt.kt:103)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104)
    at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:277)
    at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:95)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:69)
    at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source:1)
    at androidx.room.RoomDatabaseKt$startTransactionCoroutine$2$1.run(RoomDatabaseExt.kt:99)
    at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.kt:36)
    at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0)
    at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
    at java.lang.Thread.run(Thread.java:1012)
```

It looks kinda weird because "x just posted" has a different user than
the actual post, but it works for groups I guess? And definitely better
than crashing.

<img
src="https://github.com/user-attachments/assets/8110ff17-674d-4f36-8df0-453a666856a6"
width="320"/>

closes #4563
2024-09-02 20:00:27 +02:00
Konrad Pozniak
4d73a3c2e3
Fix detecting urls (#4642)
closes #4641
2024-09-02 19:56:38 +02:00
Konrad Pozniak
31e4f08966
fix account switching (#4636)
closes #4631 
closes #4629 

and other weirdness introduced in Tusky 26.1.
I did a lot of testing on 2 physical devices and multiple emulators. It
definitely is better than before, but probably still not perfect.
2024-09-02 19:49:22 +02:00
andrewhamilton0
74d479c3dc
Fixes issue where alt text positioning covers video controller (#4632)
Fixes issue where alt text positioning covers video controller
Also adds scroll view for more responsive scrolling
closes #4165
2024-09-02 18:39:23 +02:00
andrewhamilton0
49fbe1f408
Minimizes keyboard on search screen (#4633)
Adds feature if user clicks on toolbar, on the pages box, or on the tabs
buttons that the keyboard will minimize and focus will be taken off of
search bar.

Further addresses issue #4573
2024-09-01 13:28:55 +02:00
Konrad Pozniak
e23686ec70
fix timeline jumping around when new posts are inserted at the top (#4619)
This fixes a bug where the timeline would jump to the position of a
previously clicked "load more" when new post are inserted at the top
after swiping to refresh.

This only happens when "Reading order" is set to "Oldest first".

The problem is that updateReadingPositionForOldestFirst (which consumes
the marker to which it should jump) is called from onItemRangeInserted.
But onItemRangeInserted is not called everytime a "load more" is
clicked, leaving the marker active, causing a jump the next time
onItemRangeInserted is called.

I am not sure this fixes all cases of the various jumping bugs that have
been reported recently as this was the only one I could reliably
reproduce.

Related to https://github.com/tuskyapp/Tusky/issues/4493
2024-08-19 20:53:11 +02:00
Konrad Pozniak
c7387c7b52
prevent mixup of account timelines (#4599)
This does 2 things:

- Removes `AccountSwitchInterceptor`, the main culprit for the bug. APIs
can no longer change their base url after they have been created. As a
result they are not Singletons anymore.
- Additionally, I refactored how MainActivity handles Intents to make it
less likely to have multiple instances of it active.

Here is how I could reliably reproduce the bug:

- Be logged in with account A and B
- Write a post with account A, cancel it before it sends (go into flight
mode for that)
- Switch to account B
- Open the "this post failed to send" notification from account A,
drafts will open
- Go back. You are in the MainActivity of account A, everything seems
fine.
- Go back again. You are in the old, now broken MainActivity of account
B. It uses the database of account B but the network of account A.
Refreshing will show posts from A.

closes #4567 
closes #4554
closes #4402 
closes #4148
closes #2663
and possibly #4588
2024-08-14 18:58:12 +02:00
Konrad Pozniak
dfd83f3080
show correct icon for direct as default reply privacy (#4594) 2024-08-10 09:46:53 +02:00
Konrad Pozniak
b68e9760fb
fix translating boosts in home timeline (#4590)
fixes https://github.com/tuskyapp/Tusky/issues/4589
2024-08-06 20:10:38 +02:00
Konrad Pozniak
892801b83a
add more options to default reply visibility setting (#4568)
This adds `direct` and `match_default_post_visibility` as options to the
default reply visibility setting. `match_default_post_visibility` will
be the default for new accounts.

closes https://github.com/tuskyapp/Tusky/issues/4555

<img
src="https://github.com/user-attachments/assets/b256ff32-cd49-4274-903b-96da96451e0e"
width="320"/>
2024-08-02 17:15:10 +02:00
Willow
18b943fef5
Bind account early in timeline & notification view models (#4577)
This will make it less likely that data from different accounts will get
mixed up.

I checked the codepaths and we shouldn't hit viewModel if account is not
there but this is still a bit of risk to assume that so I'll investigate
if we can pass in more things and use DI to make it more secure

---------

Co-authored-by: Conny Duck <git@connyduck.at>
2024-08-02 17:13:32 +02:00