From a2ea8e76fb6c0005ecb2b44b438156d0b398b53b Mon Sep 17 00:00:00 2001 From: Grishka Date: Wed, 29 Nov 2023 02:09:59 +0300 Subject: [PATCH] Improve follow recommendations screen (AND-101) --- .../account_list/BaseAccountListFragment.java | 3 +- .../OnboardingFollowSuggestionsFragment.java | 33 +++-- .../model/viewmodel/AccountViewModel.java | 11 ++ .../ui/viewholders/AccountViewHolder.java | 49 ++++--- .../res/drawable/bg_button_m3_elevated.xml | 9 ++ .../main/res/drawable/fg_onboarding_ava.xml | 5 + ...fragment_onboarding_follow_suggestions.xml | 10 +- .../layout/item_account_list_onboarding.xml | 123 ++++++++++++++++++ mastodon/src/main/res/values/strings.xml | 3 +- mastodon/src/main/res/values/styles.xml | 8 ++ 10 files changed, 218 insertions(+), 36 deletions(-) create mode 100644 mastodon/src/main/res/drawable/bg_button_m3_elevated.xml create mode 100644 mastodon/src/main/res/drawable/fg_onboarding_ava.xml create mode 100644 mastodon/src/main/res/layout/item_account_list_onboarding.xml diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/BaseAccountListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/BaseAccountListFragment.java index 41d370717..65d6f5f39 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/BaseAccountListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/account_list/BaseAccountListFragment.java @@ -38,6 +38,7 @@ public abstract class BaseAccountListFragment extends MastodonRecyclerFragment relationships=new HashMap<>(); protected String accountID; protected ArrayList> relationshipsRequests=new ArrayList<>(); + protected int itemLayoutRes=R.layout.item_account_list; public BaseAccountListFragment(){ super(40); @@ -151,7 +152,7 @@ public abstract class BaseAccountListFragment extends MastodonRecyclerFragmentproceed())); @@ -58,9 +61,7 @@ public class OnboardingFollowSuggestionsFragment extends BaseAccountListFragment @Override protected void onUpdateToolbar(){ super.onUpdateToolbar(); - if(onScrollListener!=null){ - onScrollListener.setViews(buttonBar, getToolbar()); - } + getToolbar().setContentInsetsRelative(V.dp(56), 0); } @Override @@ -69,7 +70,7 @@ public class OnboardingFollowSuggestionsFragment extends BaseAccountListFragment .setCallback(new SimpleCallback<>(this){ @Override public void onSuccess(List result){ - onDataLoaded(result.stream().map(fs->new AccountViewModel(fs.account, accountID)).collect(Collectors.toList()), false); + onDataLoaded(result.stream().map(fs->new AccountViewModel(fs.account, accountID).stripLinksFromBio()).collect(Collectors.toList()), false); } }) .exec(accountID); @@ -80,6 +81,19 @@ public class OnboardingFollowSuggestionsFragment extends BaseAccountListFragment super.onApplyWindowInsets(UiUtils.applyBottomInsetToFixedView(buttonBar, insets)); } + @Override + protected RecyclerView.Adapter getAdapter(){ + TextView introText=new TextView(getActivity()); + introText.setTextAppearance(R.style.m3_body_large); + introText.setTextColor(UiUtils.getThemeColor(getActivity(), R.attr.colorM3OnSurface)); + introText.setPaddingRelative(V.dp(56), 0, V.dp(24), V.dp(8)); + introText.setText(R.string.onboarding_recommendations_intro); + MergeRecyclerAdapter mergeAdapter=new MergeRecyclerAdapter(); + mergeAdapter.addAdapter(new SingleViewRecyclerAdapter(introText)); + mergeAdapter.addAdapter(super.getAdapter()); + return mergeAdapter; + } + private void onFollowAllClick(View v){ if(!loaded || relationships.isEmpty()) return; @@ -155,5 +169,6 @@ public class OnboardingFollowSuggestionsFragment extends BaseAccountListFragment protected void onConfigureViewHolder(AccountViewHolder holder){ super.onConfigureViewHolder(holder); holder.setStyle(AccountViewHolder.AccessoryType.BUTTON, true); + holder.avatar.setOutlineProvider(OutlineProviders.roundedRect(8)); } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/model/viewmodel/AccountViewModel.java b/mastodon/src/main/java/org/joinmastodon/android/model/viewmodel/AccountViewModel.java index 522739223..3860e0ec2 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/model/viewmodel/AccountViewModel.java +++ b/mastodon/src/main/java/org/joinmastodon/android/model/viewmodel/AccountViewModel.java @@ -1,5 +1,6 @@ package org.joinmastodon.android.model.viewmodel; +import android.text.Spannable; import android.text.SpannableStringBuilder; import org.joinmastodon.android.GlobalUserPreferences; @@ -7,6 +8,7 @@ import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.model.Account; import org.joinmastodon.android.model.AccountField; import org.joinmastodon.android.ui.text.HtmlParser; +import org.joinmastodon.android.ui.text.LinkSpan; import org.joinmastodon.android.ui.utils.CustomEmojiHelper; import java.util.Collections; @@ -43,4 +45,13 @@ public class AccountViewModel{ } this.verifiedLink=verifiedLink; } + + public AccountViewModel stripLinksFromBio(){ + if(parsedBio instanceof Spannable spannable){ + for(LinkSpan span:spannable.getSpans(0, spannable.length(), LinkSpan.class)){ + spannable.removeSpan(span); + } + } + return this; + } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/viewholders/AccountViewHolder.java b/mastodon/src/main/java/org/joinmastodon/android/ui/viewholders/AccountViewHolder.java index ca22bab30..8df0bdc43 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/viewholders/AccountViewHolder.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/viewholders/AccountViewHolder.java @@ -44,6 +44,7 @@ import java.util.Objects; import java.util.function.Consumer; import java.util.function.Predicate; +import androidx.annotation.LayoutRes; import me.grishka.appkit.Nav; import me.grishka.appkit.api.Callback; import me.grishka.appkit.api.ErrorResponse; @@ -53,7 +54,7 @@ import me.grishka.appkit.views.UsableRecyclerView; public class AccountViewHolder extends BindableViewHolder implements ImageLoaderViewHolder, UsableRecyclerView.Clickable, UsableRecyclerView.LongClickable{ private final TextView name, username, followers, verifiedLink, bio; - private final ImageView avatar; + public final ImageView avatar; private final ProgressBarButton button; private final PopupMenu contextMenu; private final View menuAnchor; @@ -75,7 +76,11 @@ public class AccountViewHolder extends BindableViewHolder impl private boolean checked; public AccountViewHolder(Fragment fragment, ViewGroup list, HashMap relationships){ - super(fragment.getActivity(), R.layout.item_account_list, list); + this(fragment, list, relationships, R.layout.item_account_list); + } + + public AccountViewHolder(Fragment fragment, ViewGroup list, HashMap relationships, @LayoutRes int layout){ + super(fragment.getActivity(), layout, list); this.fragment=fragment; this.accountID=Objects.requireNonNull(fragment.getArguments().getString("account")); this.relationships=relationships; @@ -111,24 +116,28 @@ public class AccountViewHolder extends BindableViewHolder impl public void onBind(AccountViewModel item){ name.setText(item.parsedName); username.setText("@"+item.account.acct); - String followersStr=fragment.getResources().getQuantityString(R.plurals.x_followers, item.account.followersCount>1000 ? 999 : (int)item.account.followersCount); - String followersNum=UiUtils.abbreviateNumber(item.account.followersCount); - int index=followersStr.indexOf("%,d"); - followersStr=followersStr.replace("%,d", followersNum); - SpannableStringBuilder followersFormatted=new SpannableStringBuilder(followersStr); - if(index!=-1){ - followersFormatted.setSpan(mediumSpan, index, index+followersNum.length(), 0); + if(followers!=null){ + String followersStr=fragment.getResources().getQuantityString(R.plurals.x_followers, item.account.followersCount>1000 ? 999 : (int)item.account.followersCount); + String followersNum=UiUtils.abbreviateNumber(item.account.followersCount); + int index=followersStr.indexOf("%,d"); + followersStr=followersStr.replace("%,d", followersNum); + SpannableStringBuilder followersFormatted=new SpannableStringBuilder(followersStr); + if(index!=-1){ + followersFormatted.setSpan(mediumSpan, index, index+followersNum.length(), 0); + } + followers.setText(followersFormatted); + } + if(verifiedLink!=null){ + boolean hasVerifiedLink=item.verifiedLink!=null; + if(!hasVerifiedLink) + verifiedLink.setText(R.string.no_verified_link); + else + verifiedLink.setText(item.verifiedLink); + verifiedLink.setCompoundDrawablesRelativeWithIntrinsicBounds(hasVerifiedLink ? R.drawable.ic_check_small_16px : R.drawable.ic_help_16px, 0, 0, 0); + int tintColor=UiUtils.getThemeColor(fragment.getActivity(), hasVerifiedLink ? R.attr.colorM3Primary : R.attr.colorM3Secondary); + verifiedLink.setTextColor(tintColor); + verifiedLink.setCompoundDrawableTintList(ColorStateList.valueOf(tintColor)); } - followers.setText(followersFormatted); - boolean hasVerifiedLink=item.verifiedLink!=null; - if(!hasVerifiedLink) - verifiedLink.setText(R.string.no_verified_link); - else - verifiedLink.setText(item.verifiedLink); - verifiedLink.setCompoundDrawablesRelativeWithIntrinsicBounds(hasVerifiedLink ? R.drawable.ic_check_small_16px : R.drawable.ic_help_16px, 0, 0, 0); - int tintColor=UiUtils.getThemeColor(fragment.getActivity(), hasVerifiedLink ? R.attr.colorM3Primary : R.attr.colorM3Secondary); - verifiedLink.setTextColor(tintColor); - verifiedLink.setCompoundDrawableTintList(ColorStateList.valueOf(tintColor)); bindRelationship(); if(showBio){ bio.setText(item.parsedBio); @@ -338,7 +347,7 @@ public class AccountViewHolder extends BindableViewHolder impl Menu menu=contextMenu.getMenu(); Account account=item.account; - menu.findItem(R.id.share).setTitle(fragment.getString(R.string.share_user, account.getDisplayUsername())); + menu.findItem(R.id.share).setTitle(R.string.share_user); menu.findItem(R.id.mute).setTitle(fragment.getString(relationship.muting ? R.string.unmute_user : R.string.mute_user, account.getDisplayUsername())); menu.findItem(R.id.block).setTitle(fragment.getString(relationship.blocking ? R.string.unblock_user : R.string.block_user, account.getDisplayUsername())); menu.findItem(R.id.report).setTitle(fragment.getString(R.string.report_user, account.getDisplayUsername())); diff --git a/mastodon/src/main/res/drawable/bg_button_m3_elevated.xml b/mastodon/src/main/res/drawable/bg_button_m3_elevated.xml new file mode 100644 index 000000000..9354428dc --- /dev/null +++ b/mastodon/src/main/res/drawable/bg_button_m3_elevated.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/fg_onboarding_ava.xml b/mastodon/src/main/res/drawable/fg_onboarding_ava.xml new file mode 100644 index 000000000..c0dbe1234 --- /dev/null +++ b/mastodon/src/main/res/drawable/fg_onboarding_ava.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/mastodon/src/main/res/layout/fragment_onboarding_follow_suggestions.xml b/mastodon/src/main/res/layout/fragment_onboarding_follow_suggestions.xml index e7a180c76..80dc29bef 100644 --- a/mastodon/src/main/res/layout/fragment_onboarding_follow_suggestions.xml +++ b/mastodon/src/main/res/layout/fragment_onboarding_follow_suggestions.xml @@ -37,16 +37,16 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="end" - android:background="@drawable/bg_onboarding_panel"> + android:background="@drawable/bg_m3_surface1">