Thread fragment tweaks part 2

This commit is contained in:
Grishka
2023-11-14 21:27:15 +03:00
parent 5c9ad9286d
commit 45cc531eec
9 changed files with 412 additions and 5 deletions

View File

@@ -1,5 +1,8 @@
package org.joinmastodon.android.fragments;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ClipData;
@@ -90,12 +93,14 @@ import java.util.stream.Collectors;
import me.grishka.appkit.Nav;
import me.grishka.appkit.api.Callback;
import me.grishka.appkit.api.ErrorResponse;
import me.grishka.appkit.fragments.CustomTransitionsFragment;
import me.grishka.appkit.fragments.OnBackPressedListener;
import me.grishka.appkit.imageloader.ViewImageLoader;
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
import me.grishka.appkit.utils.CubicBezierInterpolator;
import me.grishka.appkit.utils.V;
public class ComposeFragment extends MastodonToolbarFragment implements OnBackPressedListener, ComposeEditText.SelectionListener{
public class ComposeFragment extends MastodonToolbarFragment implements OnBackPressedListener, ComposeEditText.SelectionListener, CustomTransitionsFragment{
private static final int MEDIA_RESULT=717;
public static final int IMAGE_DESCRIPTION_RESULT=363;
@@ -1124,4 +1129,35 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
private void setPostLanguage(ComposeLanguageAlertViewController.SelectedOption language){
postLang=language;
}
@Override
public Animator onCreateEnterTransition(View prev, View container){
AnimatorSet anim=new AnimatorSet();
if(getArguments().getBoolean("fromThreadFragment")){
anim.playTogether(
ObjectAnimator.ofFloat(container, View.ALPHA, 0f, 1f),
ObjectAnimator.ofFloat(container, View.TRANSLATION_Y, V.dp(200), 0)
);
}else{
anim.playTogether(
ObjectAnimator.ofFloat(container, View.ALPHA, 0f, 1f),
ObjectAnimator.ofFloat(container, View.TRANSLATION_X, V.dp(100), 0)
);
}
anim.setDuration(300);
anim.setInterpolator(CubicBezierInterpolator.DEFAULT);
return anim;
}
@Override
public Animator onCreateExitTransition(View prev, View container){
AnimatorSet anim=new AnimatorSet();
anim.playTogether(
ObjectAnimator.ofFloat(container, View.TRANSLATION_X, V.dp(100)),
ObjectAnimator.ofFloat(container, View.ALPHA, 0)
);
anim.setDuration(200);
anim.setInterpolator(CubicBezierInterpolator.DEFAULT);
return anim;
}
}

View File

@@ -2,19 +2,24 @@ package org.joinmastodon.android.fragments;
import android.content.res.ColorStateList;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.statuses.GetStatusContext;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.StatusCreatedEvent;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.FilterContext;
import org.joinmastodon.android.model.LegacyFilter;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.model.StatusContext;
import org.joinmastodon.android.ui.OutlineProviders;
import org.joinmastodon.android.ui.displayitems.ExtendedFooterStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.FooterStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.SpoilerStatusDisplayItem;
@@ -26,10 +31,12 @@ import org.parceler.Parcels;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import androidx.recyclerview.widget.RecyclerView;
import me.grishka.appkit.Nav;
import me.grishka.appkit.api.SimpleCallback;
import me.grishka.appkit.imageloader.ViewImageLoader;
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
import me.grishka.appkit.utils.MergeRecyclerAdapter;
import me.grishka.appkit.utils.SingleViewRecyclerAdapter;
import me.grishka.appkit.utils.V;
@@ -37,10 +44,16 @@ import me.grishka.appkit.utils.V;
public class ThreadFragment extends StatusListFragment{
private Status mainStatus;
private ImageView endMark;
private FrameLayout replyContainer;
private LinearLayout replyButton;
private ImageView replyButtonAva;
private TextView replyButtonText;
private int lastBottomInset;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setLayout(R.layout.fragment_thread);
mainStatus=Parcels.unwrap(getArguments().getParcelable("status"));
Account inReplyToAccount=Parcels.unwrap(getArguments().getParcelable("inReplyToAccount"));
if(inReplyToAccount!=null)
@@ -126,6 +139,20 @@ public class ThreadFragment extends StatusListFragment{
@Override
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
replyContainer=view.findViewById(R.id.reply_button_wrapper);
replyButton=replyContainer.findViewById(R.id.reply_button);
replyButtonText=replyButton.findViewById(R.id.reply_btn_text);
replyButtonAva=replyButton.findViewById(R.id.avatar);
replyButton.setOutlineProvider(OutlineProviders.roundedRect(20));
replyButton.setClipToOutline(true);
replyButtonText.setText(getString(R.string.reply_to_user, mainStatus.account.displayName));
replyButtonAva.setOutlineProvider(OutlineProviders.OVAL);
replyButtonAva.setClipToOutline(true);
replyButton.setOnClickListener(v->openReply());
Account self=AccountSessionManager.get(accountID).self;
if(!TextUtils.isEmpty(self.avatar)){
ViewImageLoader.loadWithoutAnimation(replyButtonAva, getResources().getDrawable(R.drawable.image_placeholder), new UrlImageLoaderRequest(self.avatar, V.dp(24), V.dp(24)));
}
UiUtils.loadCustomEmojiInTextView(toolbarTitleView);
showContent();
if(!loaded)
@@ -175,4 +202,22 @@ public class ThreadFragment extends StatusListFragment{
}
super.onErrorRetryClick();
}
@Override
public void onApplyWindowInsets(WindowInsets insets){
lastBottomInset=insets.getSystemWindowInsetBottom();
super.onApplyWindowInsets(UiUtils.applyBottomInsetToFixedView(replyContainer, insets));
}
private void openReply(){
Bundle args=new Bundle();
args.putString("account", accountID);
args.putParcelable("replyTo", Parcels.wrap(mainStatus));
args.putBoolean("fromThreadFragment", true);
Nav.go(getActivity(), ComposeFragment.class, args);
}
public int getSnackbarOffset(){
return replyContainer.getHeight()-lastBottomInset;
}
}