Merge remote-tracking branch 'megalodon_main/main'

# Conflicts:
#	mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java
#	mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTabFragment.java
#	mastodon/src/main/java/org/joinmastodon/android/fragments/ProfileFragment.java
#	mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java
This commit is contained in:
LucasGGamerM
2023-04-27 15:30:58 -03:00
20 changed files with 129 additions and 122 deletions

View File

@@ -49,7 +49,6 @@ import org.joinmastodon.android.ui.photoviewer.PhotoViewer;
import org.joinmastodon.android.ui.photoviewer.PhotoViewerHost;
import org.joinmastodon.android.ui.utils.MediaAttachmentViewController;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.ui.views.MediaGridLayout;
import org.joinmastodon.android.utils.TypedObjectPool;
import java.util.ArrayList;
@@ -90,10 +89,10 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
public BaseStatusListFragment(){
super(20);
if (withComposeButton()) setListLayoutId(R.layout.recycler_fragment_with_fab);
if (wantsComposeButton()) setListLayoutId(R.layout.recycler_fragment_with_fab);
}
protected boolean withComposeButton() {
protected boolean wantsComposeButton() {
return false;
}
@@ -109,8 +108,6 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
setRetainInstance(true);
}
@Override
protected RecyclerView.Adapter getAdapter(){
return adapter=new DisplayItemsAdapter();
@@ -278,6 +275,36 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
});
}
public @Nullable View getFab() {
if (getParentFragment() instanceof HasFab l) return l.getFab();
else return fab;
}
public void animateFab(boolean show) {
View fab = getFab();
if (fab == null) return;
if (show && fab.getVisibility() != View.VISIBLE) {
fab.setVisibility(View.VISIBLE);
TranslateAnimation animate = new TranslateAnimation(
0,
0,
fab.getHeight() * 2,
0);
animate.setDuration(300);
fab.startAnimation(animate);
} else if (!show && fab.getVisibility() == View.VISIBLE) {
TranslateAnimation animate = new TranslateAnimation(
0,
0,
0,
fab.getHeight() * 2);
animate.setDuration(300);
fab.startAnimation(animate);
fab.setVisibility(View.INVISIBLE);
scrollDiff = 0;
}
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
@@ -289,47 +316,21 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
if(currentPhotoViewer!=null)
currentPhotoViewer.offsetView(-dx, -dy);
if (fab!=null && GlobalUserPreferences.enableFabAutoHide) {
// This piece of code should make it so that the fab is always visible if the status list scroll view is at the item at the top
if(list.getChildAt(0).getTop() == 0){
scrollDiff= THRESHOLD +1;
}else{
if(dy > 0){
scrollDiff=0;
}
}
View fab = getFab();
if (fab!=null && GlobalUserPreferences.autoHideFab) {
if (dy > 0 && fab.getVisibility() == View.VISIBLE) {
TranslateAnimation animate = new TranslateAnimation(
0,
0,
0,
fab.getHeight() * 2);
animate.setDuration(300);
// animate.setFillAfter(true);
fab.startAnimation(animate);
fab.setEnabled(false);
fab.setVisibility(View.INVISIBLE);
scrollDiff = 0;
animateFab(false);
} else if (dy < 0 && fab.getVisibility() != View.VISIBLE) {
if (scrollDiff > THRESHOLD) {
TranslateAnimation animate = new TranslateAnimation(
0,
0,
fab.getHeight() * 2,
0);
animate.setDuration(300);
// animate.setFillAfter(true);
fab.startAnimation(animate);
fab.setEnabled(true);
fab.setVisibility(View.VISIBLE);
if (list.getChildAt(0).getTop() == 0 || scrollDiff > THRESHOLD) {
animateFab(true);
scrollDiff = 0;
} else {
scrollDiff += Math.abs(dy);
}
}
}
}});
}
});
list.addItemDecoration(new StatusListItemDecoration());
((UsableRecyclerView)list).setSelectorBoundsProvider(new UsableRecyclerView.SelectorBoundsProvider(){
private Rect tmpRect=new Rect();
@@ -364,11 +365,12 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
((UsableRecyclerView) list).setIncludeMarginsInItemHitbox(true);
updateToolbar();
if (withComposeButton()) {
fab = view.findViewById(R.id.fab);
if (wantsComposeButton() && !getArguments().getBoolean("__disable_fab", false)) {
fab.setVisibility(View.VISIBLE);
fab.setOnClickListener(this::onFabClick);
fab.setOnLongClickListener(this::onFabLongClick);
} else if (fab != null) {
fab.setVisibility(View.GONE);
}
}
@@ -696,13 +698,13 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
currentPhotoViewer.onPause();
}
protected void onFabClick(View v){
public void onFabClick(View v){
Bundle args=new Bundle();
args.putString("account", accountID);
Nav.go(getActivity(), ComposeFragment.class, args);
}
protected boolean onFabLongClick(View v) {
public boolean onFabLongClick(View v) {
return UiUtils.pickAccountForCompose(getActivity(), accountID);
}

View File

@@ -0,0 +1,7 @@
package org.joinmastodon.android.fragments;
import android.view.View;
public interface HasFab {
View getFab();
}

View File

@@ -40,7 +40,7 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment {
private MenuItem followButton;
@Override
protected boolean withComposeButton() {
protected boolean wantsComposeButton() {
return true;
}
@@ -146,12 +146,12 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment {
}
@Override
protected boolean onFabLongClick(View v) {
public boolean onFabLongClick(View v) {
return UiUtils.pickAccountForCompose(getActivity(), accountID, '#'+hashtag+' ');
}
@Override
protected void onFabClick(View v){
public void onFabClick(View v){
Bundle args=new Bundle();
args.putString("account", accountID);
args.putString("prefilledText", '#'+hashtag+' ');

View File

@@ -25,6 +25,7 @@ import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.TextView;
@@ -72,7 +73,7 @@ import me.grishka.appkit.fragments.OnBackPressedListener;
import me.grishka.appkit.utils.CubicBezierInterpolator;
import me.grishka.appkit.utils.V;
public class HomeTabFragment extends MastodonToolbarFragment implements ScrollableToTop, OnBackPressedListener, DomainDisplay {
public class HomeTabFragment extends MastodonToolbarFragment implements ScrollableToTop, OnBackPressedListener, DomainDisplay, HasFab {
private static final int ANNOUNCEMENTS_RESULT = 654;
private String accountID;
@@ -100,6 +101,7 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
private PopupMenu overflowPopup;
private View overflowActionView = null;
private boolean announcementsBadged, settingsBadged;
private ImageButton fab;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -128,6 +130,10 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
@Override
public View onCreateContentView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
FrameLayout view = new FrameLayout(getContext());
inflater.inflate(R.layout.compose_fab, view);
fab = view.findViewById(R.id.fab);
fab.setOnClickListener(this::onFabClick);
fab.setOnLongClickListener(this::onFabLongClick);
pager = new ViewPager2(getContext());
toolbarFrame = (FrameLayout) LayoutInflater.from(getContext()).inflate(R.layout.home_toolbar, getToolbar(), false);
@@ -135,6 +141,7 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
Bundle args = new Bundle();
args.putString("account", accountID);
args.putBoolean("__is_tab", true);
args.putBoolean("__disable_fab", true);
args.putBoolean("onlyPosts", true);
for (int i = 0; i < timelineDefinitions.size(); i++) {
@@ -298,6 +305,20 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
return DomainDisplay.super.getDomain();
}
private void onFabClick(View v){
if (fragments[pager.getCurrentItem()] instanceof BaseStatusListFragment<?> l) {
l.onFabClick(v);
}
}
private boolean onFabLongClick(View v) {
if (fragments[pager.getCurrentItem()] instanceof BaseStatusListFragment<?> l) {
return l.onFabLongClick(v);
} else {
return false;
}
}
private void addListsToOverflowMenu() {
Context ctx = getContext();
listsMenu.clear();
@@ -448,6 +469,7 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
private void updateSwitcherIcon(int i) {
timelineIcon.setImageResource(timelines[i].getIcon().iconRes);
timelineTitle.setText(timelines[i].getTitle(getContext()));
if (fragments[i] instanceof BaseStatusListFragment<?> l) l.animateFab(true);
}
@Override
@@ -686,6 +708,10 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
return hashtagsItems.values();
}
public ImageButton getFab() {
return fab;
}
private class HomePagerAdapter extends RecyclerView.Adapter<SimpleViewHolder> {
@NonNull
@Override

View File

@@ -38,7 +38,7 @@ public class HomeTimelineFragment extends StatusListFragment {
private String lastSavedMarkerID;
@Override
protected boolean withComposeButton() {
protected boolean wantsComposeButton() {
return true;
}

View File

@@ -44,7 +44,7 @@ public class ListTimelineFragment extends PinnableStatusListFragment {
private ListTimeline.RepliesPolicy repliesPolicy;
@Override
protected boolean withComposeButton() {
protected boolean wantsComposeButton() {
return true;
}
@@ -152,7 +152,7 @@ public class ListTimelineFragment extends PinnableStatusListFragment {
}
@Override
protected void onFabClick(View v){
public void onFabClick(View v){
Bundle args=new Bundle();
args.putString("account", accountID);
Nav.go(getActivity(), ComposeFragment.class, args);

View File

@@ -19,7 +19,6 @@ import org.joinmastodon.android.model.CacheablePaginatedResponse;
import org.joinmastodon.android.model.Emoji;
import org.joinmastodon.android.model.Filter;
import org.joinmastodon.android.model.Notification;
import org.joinmastodon.android.model.PaginatedResponse;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.displayitems.AccountCardStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem;
@@ -50,8 +49,8 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
private final DiscoverInfoBannerHelper bannerHelper = new DiscoverInfoBannerHelper(DiscoverInfoBannerHelper.BannerType.POST_NOTIFICATIONS);
@Override
protected boolean withComposeButton() {
return true;
protected boolean wantsComposeButton() {
return false;
}
@Override
@@ -107,7 +106,8 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
case UPDATE -> getString(R.string.sk_post_edited);
case SIGN_UP -> getString(R.string.sk_signed_up);
case REPORT -> getString(R.string.sk_reported);
case EMOJI_REACTION -> getString(R.string.sk_reacted, n.emoji);
case REACTION, PLEROMA_EMOJI_REACTION ->
n.emoji != null ? getString(R.string.sk_reacted_with, n.emoji) : getString(R.string.sk_reacted);
};
HeaderStatusDisplayItem titleItem=extraText!=null ? new HeaderStatusDisplayItem(n.id, n.account, n.createdAt, this, accountID, n.status, n.emojiUrl!=null ? HtmlParser.parseCustomEmoji(extraText, Collections.singletonList(emoji)) : extraText, n, null) : null;
if(n.status!=null){
@@ -214,7 +214,6 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
list.addItemDecoration(new InsetStatusItemDecoration(this));
if (getParentFragment() instanceof NotificationsFragment) fab.setVisibility(View.GONE);
if (onlyPosts) bannerHelper.maybeAddBanner(contentWrap);
}

View File

@@ -115,7 +115,7 @@ import me.grishka.appkit.utils.CubicBezierInterpolator;
import me.grishka.appkit.utils.V;
import me.grishka.appkit.views.UsableRecyclerView;
public class ProfileFragment extends LoaderFragment implements OnBackPressedListener, ScrollableToTop{
public class ProfileFragment extends LoaderFragment implements OnBackPressedListener, ScrollableToTop, HasFab{
private static final int AVATAR_RESULT=722;
private static final int COVER_RESULT=343;
@@ -158,7 +158,6 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
private WindowInsets childInsets;
private PhotoViewer currentPhotoViewer;
private boolean editModeLoading;
protected int scrollDiff = 0;
private static final int MAX_FIELDS=4;
@@ -232,7 +231,6 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
followingCount=content.findViewById(R.id.following_count);
followingLabel=content.findViewById(R.id.following_label);
followingBtn=content.findViewById(R.id.following_btn);
postsCount=content.findViewById(R.id.posts_count);
postsLabel=content.findViewById(R.id.posts_label);
postsBtn=content.findViewById(R.id.posts_btn);
@@ -594,7 +592,6 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
boolean isSelf=AccountSessionManager.getInstance().isSelf(accountID, account);
if(account.locked){
ssb=new SpannableStringBuilder("@");
ssb.append(account.acct);
@@ -902,36 +899,6 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
if(currentPhotoViewer!=null){
currentPhotoViewer.offsetView(0, oldScrollY-scrollY);
}
if(GlobalUserPreferences.enableFabAutoHide){
int dy = scrollY - oldScrollY;
if (dy > 0 && fab.getVisibility() == View.VISIBLE) {
TranslateAnimation animate = new TranslateAnimation(
0,
0,
0,
fab.getHeight() * 2);
animate.setDuration(300);
fab.startAnimation(animate);
fab.setVisibility(View.INVISIBLE);
scrollDiff = 0;
} else if (dy < 0 && fab.getVisibility() != View.VISIBLE) {
if (scrollDiff > 400) {
fab.setVisibility(View.VISIBLE);
TranslateAnimation animate = new TranslateAnimation(
0,
0,
fab.getHeight() * 2,
0);
animate.setDuration(300);
fab.startAnimation(animate);
scrollDiff = 0;
} else {
scrollDiff += Math.abs(dy);
}
}
}
}
private Fragment getFragmentForPage(int page){

View File

@@ -32,7 +32,7 @@ public class ScheduledStatusListFragment extends BaseStatusListFragment<Schedule
private static final int SCHEDULED_STATUS_LIST_OPENED = 161;
@Override
protected boolean withComposeButton() {
protected boolean wantsComposeButton() {
return true;
}
@@ -57,7 +57,7 @@ public class ScheduledStatusListFragment extends BaseStatusListFragment<Schedule
}
@Override
protected void onFabClick(View v) {
public void onFabClick(View v) {
Bundle args=new Bundle();
args.putString("account", accountID);
args.putSerializable("scheduledAt", CreateStatus.getDraftInstant());
@@ -65,7 +65,7 @@ public class ScheduledStatusListFragment extends BaseStatusListFragment<Schedule
}
@Override
protected boolean onFabLongClick(View v) {
public boolean onFabLongClick(View v) {
Bundle args=new Bundle();
args.putString("account", accountID);
args.putSerializable("scheduledAt", CreateStatus.getDraftInstant());

View File

@@ -21,7 +21,7 @@ public class FederatedTimelineFragment extends StatusListFragment {
private String maxID;
@Override
protected boolean withComposeButton() {
protected boolean wantsComposeButton() {
return true;
}

View File

@@ -20,7 +20,7 @@ public class LocalTimelineFragment extends StatusListFragment {
private String maxID;
@Override
protected boolean withComposeButton() {
protected boolean wantsComposeButton() {
return true;
}

View File

@@ -53,12 +53,14 @@ public class Notification extends BaseModel implements DisplayItemsParent{
STATUS,
@SerializedName("update")
UPDATE,
@SerializedName("reaction")
REACTION,
@SerializedName("pleroma:emoji_reaction")
PLEROMA_EMOJI_REACTION,
@SerializedName("admin.sign_up")
SIGN_UP,
@SerializedName("admin.report")
REPORT,
@SerializedName("pleroma:emoji_reaction")
EMOJI_REACTION
REPORT
}
@Parcel

View File

@@ -207,7 +207,6 @@ public abstract class StatusDisplayItem{
items.add(new GapStatusDisplayItem(parentID, fragment));
}
}
int i=1;
for(StatusDisplayItem item:items){
item.inset=inset;

File diff suppressed because one or more lines are too long