Allow returning to previous scroll position in home timeline (AND-189)
This commit is contained in:
parent
ced5fe4ee0
commit
2ad50cd972
@ -9,7 +9,9 @@ import android.app.Activity;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.VibrationEffect;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.style.ForegroundColorSpan;
|
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.DonationSheet;
|
||||||
import org.joinmastodon.android.ui.sheets.DonationSuccessfulSheet;
|
import org.joinmastodon.android.ui.sheets.DonationSuccessfulSheet;
|
||||||
import org.joinmastodon.android.ui.utils.DiscoverInfoBannerHelper;
|
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.HomeTimelineMenuController;
|
||||||
import org.joinmastodon.android.ui.viewcontrollers.ToolbarDropdownMenuController;
|
import org.joinmastodon.android.ui.viewcontrollers.ToolbarDropdownMenuController;
|
||||||
import org.joinmastodon.android.ui.views.FixedAspectRatioImageView;
|
import org.joinmastodon.android.ui.views.FixedAspectRatioImageView;
|
||||||
@ -106,6 +109,11 @@ public class HomeTimelineFragment extends StatusListFragment implements ToolbarD
|
|||||||
private DiscoverInfoBannerHelper localTimelineBannerHelper;
|
private DiscoverInfoBannerHelper localTimelineBannerHelper;
|
||||||
private View donationBanner;
|
private View donationBanner;
|
||||||
private boolean donationBannerDismissing;
|
private boolean donationBannerDismissing;
|
||||||
|
private NestedRecyclerScrollView scrollWrapper;
|
||||||
|
|
||||||
|
private String scrollBackItemID;
|
||||||
|
private int scrollBackItemOffset, scrollBackItemIndex;
|
||||||
|
private long scrollBackTime;
|
||||||
|
|
||||||
private String maxID;
|
private String maxID;
|
||||||
private String lastSavedMarkerID;
|
private String lastSavedMarkerID;
|
||||||
@ -323,6 +331,7 @@ public class HomeTimelineFragment extends StatusListFragment implements ToolbarD
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
scrollWrapper=scroller;
|
||||||
|
|
||||||
if(GithubSelfUpdater.needSelfUpdating()){
|
if(GithubSelfUpdater.needSelfUpdating()){
|
||||||
updateUpdateState(GithubSelfUpdater.getInstance().getState());
|
updateUpdateState(GithubSelfUpdater.getInstance().getState());
|
||||||
@ -728,7 +737,7 @@ public class HomeTimelineFragment extends StatusListFragment implements ToolbarD
|
|||||||
private void onNewPostsBtnClick(View v){
|
private void onNewPostsBtnClick(View v){
|
||||||
if(newPostsBtnShown){
|
if(newPostsBtnShown){
|
||||||
hideNewPostsButton();
|
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<displayItems.size();i++){
|
||||||
|
StatusDisplayItem item=displayItems.get(i);
|
||||||
|
if(item.parentID.equals(scrollBackItemID)){
|
||||||
|
if(indexWithinPost==scrollBackItemIndex){
|
||||||
|
((LinearLayoutManager)list.getLayoutManager()).scrollToPositionWithOffset(i+getMainAdapterOffset(), scrollBackItemOffset);
|
||||||
|
list.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener(){
|
||||||
|
@Override
|
||||||
|
public boolean onPreDraw(){
|
||||||
|
list.getViewTreeObserver().removeOnPreDrawListener(this);
|
||||||
|
list.scrollBy(0, V.dp(-300));
|
||||||
|
list.smoothScrollBy(0, V.dp(300));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(Build.VERSION.SDK_INT>=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;postIndex<data.size();postIndex++){
|
||||||
|
if(data.get(postIndex).id.equals(id))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(postIndex>1){
|
||||||
|
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(){
|
private String getCurrentListTitle(){
|
||||||
return switch(listMode){
|
return switch(listMode){
|
||||||
case FOLLOWING -> getString(R.string.timeline_following);
|
case FOLLOWING -> getString(R.string.timeline_following);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.joinmastodon.android.ui.utils;
|
package org.joinmastodon.android.ui.utils;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.annotation.TargetApi;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.UiModeManager;
|
import android.app.UiModeManager;
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
@ -25,6 +26,8 @@ import android.os.Bundle;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
import android.os.VibrationEffect;
|
||||||
|
import android.os.Vibrator;
|
||||||
import android.os.ext.SdkExtensions;
|
import android.os.ext.SdkExtensions;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
import android.provider.OpenableColumns;
|
import android.provider.OpenableColumns;
|
||||||
@ -1106,4 +1109,14 @@ public class UiUtils{
|
|||||||
return ColorContrastMode.DEFAULT;
|
return ColorContrastMode.DEFAULT;
|
||||||
return ColorContrastMode.fromContrastValue(context.getSystemService(UiModeManager.class).getContrast());
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -350,11 +350,7 @@ public class ComposePollViewController{
|
|||||||
pollOptionsView.removeView(view);
|
pollOptionsView.removeView(view);
|
||||||
addPollOptionBtn.setEnabled(pollOptions.size()<maxPollOptions);
|
addPollOptionBtn.setEnabled(pollOptions.size()<maxPollOptions);
|
||||||
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.R){
|
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.R){
|
||||||
Vibrator vibrator=fragment.getActivity().getSystemService(Vibrator.class);
|
UiUtils.playVibrationEffectIfSupported(fragment.getActivity(), VibrationEffect.Composition.PRIMITIVE_QUICK_RISE);
|
||||||
if(vibrator.areAllPrimitivesSupported(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE)){
|
|
||||||
VibrationEffect effect=VibrationEffect.startComposition().addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE).compose();
|
|
||||||
vibrator.vibrate(effect);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user