diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTimelineFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTimelineFragment.java index 05baf106..aab0f096 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTimelineFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTimelineFragment.java @@ -9,7 +9,9 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; +import android.os.Build; import android.os.Bundle; +import android.os.VibrationEffect; import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.style.ForegroundColorSpan; @@ -58,6 +60,7 @@ import org.joinmastodon.android.ui.displayitems.StatusDisplayItem; import org.joinmastodon.android.ui.sheets.DonationSheet; import org.joinmastodon.android.ui.sheets.DonationSuccessfulSheet; import org.joinmastodon.android.ui.utils.DiscoverInfoBannerHelper; +import org.joinmastodon.android.ui.utils.UiUtils; import org.joinmastodon.android.ui.viewcontrollers.HomeTimelineMenuController; import org.joinmastodon.android.ui.viewcontrollers.ToolbarDropdownMenuController; import org.joinmastodon.android.ui.views.FixedAspectRatioImageView; @@ -106,6 +109,11 @@ public class HomeTimelineFragment extends StatusListFragment implements ToolbarD private DiscoverInfoBannerHelper localTimelineBannerHelper; private View donationBanner; private boolean donationBannerDismissing; + private NestedRecyclerScrollView scrollWrapper; + + private String scrollBackItemID; + private int scrollBackItemOffset, scrollBackItemIndex; + private long scrollBackTime; private String maxID; private String lastSavedMarkerID; @@ -323,6 +331,7 @@ public class HomeTimelineFragment extends StatusListFragment implements ToolbarD return true; } }); + scrollWrapper=scroller; if(GithubSelfUpdater.needSelfUpdating()){ updateUpdateState(GithubSelfUpdater.getInstance().getState()); @@ -728,7 +737,7 @@ public class HomeTimelineFragment extends StatusListFragment implements ToolbarD private void onNewPostsBtnClick(View v){ if(newPostsBtnShown){ hideNewPostsButton(); - scrollToTop(); + smoothScrollRecyclerViewToTop(list); } } @@ -835,6 +844,67 @@ public class HomeTimelineFragment extends StatusListFragment implements ToolbarD } } + @Override + public void scrollToTop(){ + if(list.getChildCount()==0) + return; + scrollWrapper.smoothScrollTo(0, 0); + View topChild=list.getLayoutManager().getChildAt(0); + if(list.getChildAdapterPosition(topChild)==0){ + if(topChild.getTop()==list.getPaddingTop() && scrollBackItemID!=null && System.currentTimeMillis()-scrollBackTime<5*60_000){ + int indexWithinPost=0; + for(int i=0;i=Build.VERSION_CODES.S) + UiUtils.playVibrationEffectIfSupported(getActivity(), VibrationEffect.Composition.PRIMITIVE_THUD); + return; + } + indexWithinPost++; + } + } + }else{ + smoothScrollRecyclerViewToTop(list); + } + }else if(list.getChildViewHolder(topChild) instanceof StatusDisplayItem.Holder itemHolder){ + int postIndex; + String id=itemHolder.getItemID(); + for(postIndex=0;postIndex1){ + scrollBackItemID=id; + scrollBackItemIndex=0; + for(StatusDisplayItem item:displayItems){ + if(item.parentID.equals(id)){ + if(item==itemHolder.getItem()) + break; + scrollBackItemIndex++; + } + } + scrollBackItemOffset=topChild.getTop(); + scrollBackTime=System.currentTimeMillis(); + }else{ + scrollBackItemID=null; + } + } + smoothScrollRecyclerViewToTop(list); + if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.S) + UiUtils.playVibrationEffectIfSupported(getActivity(), VibrationEffect.Composition.PRIMITIVE_QUICK_RISE); + } + private String getCurrentListTitle(){ return switch(listMode){ case FOLLOWING -> getString(R.string.timeline_following); diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java index c04c0ea4..facc3fdc 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java @@ -1,6 +1,7 @@ package org.joinmastodon.android.ui.utils; import android.annotation.SuppressLint; +import android.annotation.TargetApi; import android.app.Activity; import android.app.UiModeManager; import android.content.ActivityNotFoundException; @@ -25,6 +26,8 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.SystemClock; +import android.os.VibrationEffect; +import android.os.Vibrator; import android.os.ext.SdkExtensions; import android.provider.MediaStore; import android.provider.OpenableColumns; @@ -1106,4 +1109,14 @@ public class UiUtils{ return ColorContrastMode.DEFAULT; return ColorContrastMode.fromContrastValue(context.getSystemService(UiModeManager.class).getContrast()); } + + @TargetApi(Build.VERSION_CODES.R) + public static boolean playVibrationEffectIfSupported(Context context, int effect){ + Vibrator vibrator=context.getSystemService(Vibrator.class); + if(vibrator.areAllPrimitivesSupported(effect)){ + vibrator.vibrate(VibrationEffect.startComposition().addPrimitive(effect).compose()); + return true; + } + return false; + } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/viewcontrollers/ComposePollViewController.java b/mastodon/src/main/java/org/joinmastodon/android/ui/viewcontrollers/ComposePollViewController.java index c22a4ecc..701cee34 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/viewcontrollers/ComposePollViewController.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/viewcontrollers/ComposePollViewController.java @@ -350,11 +350,7 @@ public class ComposePollViewController{ pollOptionsView.removeView(view); addPollOptionBtn.setEnabled(pollOptions.size()=Build.VERSION_CODES.R){ - Vibrator vibrator=fragment.getActivity().getSystemService(Vibrator.class); - if(vibrator.areAllPrimitivesSupported(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE)){ - VibrationEffect effect=VibrationEffect.startComposition().addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE).compose(); - vibrator.vibrate(effect); - } + UiUtils.playVibrationEffectIfSupported(fragment.getActivity(), VibrationEffect.Composition.PRIMITIVE_QUICK_RISE); } return; }