From 2023e55bfd3be971e75dc1c7ea623b0d3339ebdd Mon Sep 17 00:00:00 2001 From: Grishka Date: Sat, 15 Jun 2024 15:54:25 +0300 Subject: [PATCH] New design for "explore -> news" --- mastodon/build.gradle | 2 +- .../discover/DiscoverNewsFragment.java | 178 +++++------------- .../ui/utils/DiscoverInfoBannerHelper.java | 4 + .../ui/viewholders/LinkCardHolder.java | 12 +- .../main/res/layout/item_trending_link.xml | 46 ----- .../res/layout/item_trending_link_card.xml | 44 ----- 6 files changed, 65 insertions(+), 221 deletions(-) delete mode 100644 mastodon/src/main/res/layout/item_trending_link.xml delete mode 100644 mastodon/src/main/res/layout/item_trending_link_card.xml diff --git a/mastodon/build.gradle b/mastodon/build.gradle index 0328eaae..7d4f50c6 100644 --- a/mastodon/build.gradle +++ b/mastodon/build.gradle @@ -13,7 +13,7 @@ android { applicationId "org.joinmastodon.android" minSdk 23 targetSdk 33 - versionCode 100 + versionCode 101 versionName "2.5.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/DiscoverNewsFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/DiscoverNewsFragment.java index 6a9e13d1..7bc98864 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/DiscoverNewsFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/discover/DiscoverNewsFragment.java @@ -2,56 +2,35 @@ package org.joinmastodon.android.fragments.discover; import android.annotation.SuppressLint; import android.graphics.Rect; -import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; -import org.joinmastodon.android.R; import org.joinmastodon.android.api.requests.trends.GetTrendingLinks; import org.joinmastodon.android.fragments.ScrollableToTop; import org.joinmastodon.android.model.Card; import org.joinmastodon.android.model.viewmodel.CardViewModel; -import org.joinmastodon.android.ui.DividerItemDecoration; -import org.joinmastodon.android.ui.OutlineProviders; -import org.joinmastodon.android.ui.drawables.BlurhashCrossfadeDrawable; import org.joinmastodon.android.ui.utils.DiscoverInfoBannerHelper; -import org.joinmastodon.android.ui.utils.HorizontalScrollingTouchListener; -import org.joinmastodon.android.ui.utils.UiUtils; +import org.joinmastodon.android.ui.viewholders.LinkCardHolder; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import androidx.annotation.NonNull; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import me.grishka.appkit.api.SimpleCallback; import me.grishka.appkit.fragments.BaseRecyclerFragment; import me.grishka.appkit.imageloader.ImageLoaderRecyclerAdapter; -import me.grishka.appkit.imageloader.ImageLoaderViewHolder; -import me.grishka.appkit.imageloader.ListImageLoaderAdapter; import me.grishka.appkit.imageloader.ListImageLoaderWrapper; -import me.grishka.appkit.imageloader.RecyclerViewDelegate; import me.grishka.appkit.imageloader.requests.ImageLoaderRequest; -import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest; -import me.grishka.appkit.utils.BindableViewHolder; import me.grishka.appkit.utils.MergeRecyclerAdapter; -import me.grishka.appkit.utils.SingleViewRecyclerAdapter; import me.grishka.appkit.utils.V; import me.grishka.appkit.views.UsableRecyclerView; -public class DiscoverNewsFragment extends BaseRecyclerFragment implements ScrollableToTop{ +public class DiscoverNewsFragment extends BaseRecyclerFragment implements ScrollableToTop{ private String accountID; private DiscoverInfoBannerHelper bannerHelper; private MergeRecyclerAdapter mergeAdapter; - private UsableRecyclerView cardsList; - private ArrayList top3=new ArrayList<>(); - private CardLinksAdapter cardsAdapter; public DiscoverNewsFragment(){ super(10); @@ -70,12 +49,14 @@ public class DiscoverNewsFragment extends BaseRecyclerFragment im .setCallback(new SimpleCallback<>(this){ @Override public void onSuccess(List result){ - top3.clear(); - top3.addAll(result.subList(0, Math.min(3, result.size())).stream().map(card->new CardViewModel(card, 280, 140, card, accountID)).collect(Collectors.toList())); - cardsAdapter.notifyDataSetChanged(); - - onDataLoaded(result.subList(top3.size(), result.size()).stream() - .map(card->new CardViewModel(card, 56, 56, card, accountID)) + int[] index={0}; + onDataLoaded(result.stream() + .map(card->{ + int actualIndex=index[0]+(refreshing ? 0 : (data.size()+preloadedData.size())); + index[0]++; + int size=actualIndex==0 ? 1000 : 192; + return new CardItem(new CardViewModel(card, size, size, card, accountID)); + }) .collect(Collectors.toList()), false); bannerHelper.onBannerBecameVisible(); } @@ -86,27 +67,9 @@ public class DiscoverNewsFragment extends BaseRecyclerFragment im @SuppressLint("ClickableViewAccessibility") @Override protected RecyclerView.Adapter getAdapter(){ - cardsList=new UsableRecyclerView(getActivity()); - cardsList.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false)); - ListImageLoaderWrapper cardsImageLoader=new ListImageLoaderWrapper(getActivity(), cardsList, new RecyclerViewDelegate(cardsList), this); - cardsList.setAdapter(cardsAdapter=new CardLinksAdapter(cardsImageLoader, top3)); - cardsList.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, V.dp(256))); - cardsList.setPadding(V.dp(16), V.dp(8), 0, 0); - cardsList.setClipToPadding(false); - cardsList.addItemDecoration(new RecyclerView.ItemDecoration(){ - @Override - public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state){ - outRect.right=V.dp(16); - } - }); - cardsList.setSelector(R.drawable.bg_rect_12dp_ripple); - cardsList.setDrawSelectorOnTop(true); - cardsList.setOnTouchListener(new HorizontalScrollingTouchListener(getActivity())); - mergeAdapter=new MergeRecyclerAdapter(); bannerHelper.maybeAddBanner(list, mergeAdapter); - mergeAdapter.addAdapter(new SingleViewRecyclerAdapter(cardsList)); - mergeAdapter.addAdapter(new LinksAdapter(imgLoader, data)); + mergeAdapter.addAdapter(new LinksAdapter(imgLoader)); return mergeAdapter; } @@ -115,18 +78,46 @@ public class DiscoverNewsFragment extends BaseRecyclerFragment im smoothScrollRecyclerViewToTop(list); } - private class LinksAdapter extends UsableRecyclerView.Adapter implements ImageLoaderRecyclerAdapter{ - private final List data; + @Override + public void onViewCreated(View view, Bundle savedInstanceState){ + super.onViewCreated(view, savedInstanceState); + list.addItemDecoration(new RecyclerView.ItemDecoration(){ + @Override + public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state){ + if(parent.getChildAdapterPosition(view)==0 && !bannerHelper.isBannerShown()){ + outRect.top=V.dp(16); + } + if(parent.getChildViewHolder(view) instanceof LinkCardHolder){ + outRect.bottom=V.dp(8); + } + } + }); + } - public LinksAdapter(ListImageLoaderWrapper imgLoader, List data){ + public static class CardItem implements LinkCardHolder.LinkCardProvider{ + public final CardViewModel card; + + private CardItem(CardViewModel card){ + this.card=card; + } + + @Override + public CardViewModel getCard(){ + return card; + } + } + + private class LinksAdapter extends UsableRecyclerView.Adapter> implements ImageLoaderRecyclerAdapter{ + public LinksAdapter(ListImageLoaderWrapper imgLoader){ super(imgLoader); - this.data=data; } @NonNull @Override - public BaseLinkViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){ - return new LinkViewHolder(); + public LinkCardHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){ + LinkCardHolder vh=new LinkCardHolder<>(getActivity(), list, viewType==1, accountID); + vh.setTryResolving(false); + return vh; } @Override @@ -135,91 +126,24 @@ public class DiscoverNewsFragment extends BaseRecyclerFragment im } @Override - public void onBindViewHolder(BaseLinkViewHolder holder, int position){ - holder.bind(data.get(position).card); + public void onBindViewHolder(LinkCardHolder holder, int position){ + holder.bind(data.get(position)); super.onBindViewHolder(holder, position); } @Override public int getImageCountForItem(int position){ - return data.get(position).imageRequest==null ? 0 : 1; + return data.get(position).card.getImageCount(); } @Override public ImageLoaderRequest getImageRequest(int position, int image){ - return data.get(position).imageRequest; - } - } - - private class CardLinksAdapter extends LinksAdapter{ - public CardLinksAdapter(ListImageLoaderWrapper imgLoader, List data){ - super(imgLoader, data); - } - - @NonNull - @Override - public BaseLinkViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){ - return new LinkCardViewHolder(); - } - } - - private class BaseLinkViewHolder extends BindableViewHolder implements UsableRecyclerView.Clickable, ImageLoaderViewHolder{ - protected final TextView name, title; - protected final ImageView photo; - private BlurhashCrossfadeDrawable crossfadeDrawable=new BlurhashCrossfadeDrawable(); - private boolean didClear; - - public BaseLinkViewHolder(int layout){ - super(getActivity(), layout, list); - name=findViewById(R.id.name); - title=findViewById(R.id.title); - photo=findViewById(R.id.photo); + return data.get(position).card.getImageRequest(image); } @Override - public void onBind(Card item){ - name.setText(item.providerName); - title.setText(item.title); - crossfadeDrawable.setSize(item.width, item.height); - crossfadeDrawable.setBlurhashDrawable(item.blurhashPlaceholder); - crossfadeDrawable.setCrossfadeAlpha(0f); - photo.setImageDrawable(null); - photo.setImageDrawable(crossfadeDrawable); - didClear=false; - } - - @Override - public void setImage(int index, Drawable drawable){ - crossfadeDrawable.setImageDrawable(drawable); - if(didClear) - crossfadeDrawable.animateAlpha(0f); - } - - @Override - public void clearImage(int index){ - crossfadeDrawable.setCrossfadeAlpha(1f); - didClear=true; - } - - @Override - public void onClick(){ - UiUtils.launchWebBrowser(getActivity(), item.url); - } - } - - private class LinkViewHolder extends BaseLinkViewHolder{ - public LinkViewHolder(){ - super(R.layout.item_trending_link); - photo.setOutlineProvider(OutlineProviders.roundedRect(12)); - photo.setClipToOutline(true); - } - } - - private class LinkCardViewHolder extends BaseLinkViewHolder{ - public LinkCardViewHolder(){ - super(R.layout.item_trending_link_card); - itemView.setOutlineProvider(OutlineProviders.roundedRect(12)); - itemView.setClipToOutline(true); + public int getItemViewType(int position){ + return position==0 ? 1 : 2; } } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/DiscoverInfoBannerHelper.java b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/DiscoverInfoBannerHelper.java index b0247b0d..26127570 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/DiscoverInfoBannerHelper.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/DiscoverInfoBannerHelper.java @@ -85,6 +85,10 @@ public class DiscoverInfoBannerHelper{ bannerTypesToShow=EnumSet.allOf(BannerType.class); } + public boolean isBannerShown(){ + return added; + } + public enum BannerType{ TRENDING_POSTS, TRENDING_LINKS, diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/viewholders/LinkCardHolder.java b/mastodon/src/main/java/org/joinmastodon/android/ui/viewholders/LinkCardHolder.java index 0dc9e9b0..ece3255e 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/viewholders/LinkCardHolder.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/viewholders/LinkCardHolder.java @@ -20,7 +20,6 @@ import org.joinmastodon.android.ui.OutlineProviders; import org.joinmastodon.android.ui.displayitems.StatusDisplayItem; import org.joinmastodon.android.ui.drawables.BlurhashCrossfadeDrawable; import org.joinmastodon.android.ui.text.HtmlParser; -import org.joinmastodon.android.ui.utils.CustomEmojiHelper; import org.joinmastodon.android.ui.utils.UiUtils; import org.parceler.Parcels; @@ -28,7 +27,6 @@ import java.util.Objects; import me.grishka.appkit.Nav; import me.grishka.appkit.imageloader.ImageLoaderViewHolder; -import me.grishka.appkit.imageloader.requests.ImageLoaderRequest; import me.grishka.appkit.utils.V; public class LinkCardHolder extends StatusDisplayItem.Holder implements ImageLoaderViewHolder{ @@ -41,6 +39,7 @@ public class LinkCardHolder extends S private final Drawable logoIcon; private final String accountID; private Activity activity; + private boolean tryResolving=true; public LinkCardHolder(Activity context, ViewGroup parent, boolean isLarge, String accountID){ super(context, isLarge ? R.layout.display_item_link_card : R.layout.display_item_link_card_compact, parent); @@ -172,9 +171,16 @@ public class LinkCardHolder extends S } } + public void setTryResolving(boolean tryResolving){ + this.tryResolving=tryResolving; + } + private void onClick(View v){ CardViewModel card=item.getCard(); - UiUtils.openURL(itemView.getContext(), accountID, card.card.url, card.parentObject); + if(tryResolving) + UiUtils.openURL(activity, accountID, card.card.url, card.parentObject); + else + UiUtils.launchWebBrowser(activity, card.card.url); } private void onAuthorChipClick(View v){ diff --git a/mastodon/src/main/res/layout/item_trending_link.xml b/mastodon/src/main/res/layout/item_trending_link.xml deleted file mode 100644 index c426aa73..00000000 --- a/mastodon/src/main/res/layout/item_trending_link.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/mastodon/src/main/res/layout/item_trending_link_card.xml b/mastodon/src/main/res/layout/item_trending_link_card.xml deleted file mode 100644 index c829b19c..00000000 --- a/mastodon/src/main/res/layout/item_trending_link_card.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - \ No newline at end of file