Currently translated at 100.0% (677 of 677 strings)
Translated using Weblate (Persian)
Currently translated at 100.0% (677 of 677 strings)
Co-authored-by: Danial Behzadi <dani.behzi@ubuntu.com>
Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/fa/
Translation: Tusky/Tusky
Currently translated at 99.1% (671 of 677 strings)
Translated using Weblate (Dutch)
Currently translated at 99.1% (671 of 677 strings)
Co-authored-by: joenepraat <joenepraat@posteo.org>
Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/nl/
Translation: Tusky/Tusky
Currently translated at 100.0% (677 of 677 strings)
Translated using Weblate (Vietnamese)
Currently translated at 100.0% (677 of 677 strings)
Co-authored-by: Hồ Nhất Duy <mastoduy@gmail.com>
Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/vi/
Translation: Tusky/Tusky
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#4331closes#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"/>
- use `runTest` instead of `runBlocking`, where possible
- run all Robolectric tests on Api 34 (where we have most users)
- some new testcase for `TimestampUtilsTest`
- move our only instrumented Android Test, `MigrationsTest`, to unit
test so it runs in CI and expand it to test all migrations
- upgrade Robolectric
- removed truth and espresso as they are no longer needed
```
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)
```
Currently translated at 99.0% (646 of 652 strings)
Co-authored-by: Anna (cybertailor) Vyalkova <cyber@sysrq.in>
Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/ru/
Translation: Tusky/Tusky
Currently translated at 100.0% (652 of 652 strings)
Translated using Weblate (Welsh)
Currently translated at 100.0% (652 of 652 strings)
Co-authored-by: Rhoslyn Prys <post@meddal.com>
Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/cy/
Translation: Tusky/Tusky
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
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
Currently translated at 100.0% (652 of 652 strings)
Translated using Weblate (Vietnamese)
Currently translated at 100.0% (652 of 652 strings)
Co-authored-by: Hồ Nhất Duy <mastoduy@gmail.com>
Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/vi/
Translation: Tusky/Tusky
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>
Currently translated at 35.5% (232 of 652 strings)
Co-authored-by: ButterflyOfFire <butterflyoffire@protonmail.com>
Translate-URL: https://weblate.tusky.app/projects/tusky/tusky/kab/
Translation: Tusky/Tusky