tweak account card design

closes sk22#731
This commit is contained in:
sk 2023-08-25 17:20:54 +02:00
parent 86081654fb
commit aa9e66e6a2
14 changed files with 172 additions and 84 deletions

View File

@ -201,7 +201,7 @@ public class FollowRequestsListFragment extends MastodonRecyclerFragment<FollowR
}
// literally the same as AccountCardStatusDisplayItem and DiscoverAccountsFragment. code should be generalized
private class AccountViewHolder extends BindableViewHolder<AccountWrapper> implements ImageLoaderViewHolder, UsableRecyclerView.Clickable{
private class AccountViewHolder extends BindableViewHolder<AccountWrapper> implements ImageLoaderViewHolder, UsableRecyclerView.DisableableClickable{
private final ImageView cover, avatar;
private final TextView name, username, bio, followersCount, followingCount, postsCount, followersLabel, followingLabel, postsLabel;
private final ProgressBarButton actionButton, acceptButton, rejectButton;
@ -233,15 +233,24 @@ public class FollowRequestsListFragment extends MastodonRecyclerFragment<FollowR
rejectProgress=findViewById(R.id.reject_progress);
rejectWrap=findViewById(R.id.reject_btn_wrap);
itemView.setOutlineProvider(OutlineProviders.roundedRect(6));
itemView.setClipToOutline(true);
avatar.setOutlineProvider(OutlineProviders.roundedRect(12));
avatar.setOutlineProvider(OutlineProviders.roundedRect(15));
avatar.setClipToOutline(true);
cover.setOutlineProvider(OutlineProviders.roundedRect(3));
View border=findViewById(R.id.avatar_border);
border.setOutlineProvider(OutlineProviders.roundedRect(17));
border.setClipToOutline(true);
cover.setOutlineProvider(OutlineProviders.roundedRect(9));
cover.setClipToOutline(true);
itemView.setOutlineProvider(OutlineProviders.roundedRect(12));
itemView.setClipToOutline(true);
actionButton.setOnClickListener(this::onActionButtonClick);
acceptButton.setOnClickListener(this::onFollowRequestButtonClick);
rejectButton.setOnClickListener(this::onFollowRequestButtonClick);
itemView.setOnClickListener(v->this.onClick());
}
@Override
public boolean isEnabled(){
return false;
}
@Override
@ -254,26 +263,23 @@ public class FollowRequestsListFragment extends MastodonRecyclerFragment<FollowR
postsCount.setText(UiUtils.abbreviateNumber(item.account.statusesCount));
followersLabel.setText(getResources().getQuantityString(R.plurals.followers, (int)Math.min(999, item.account.followersCount)));
followingLabel.setText(getResources().getQuantityString(R.plurals.following, (int)Math.min(999, item.account.followingCount)));
postsLabel.setText(getResources().getQuantityString(R.plurals.x_posts, (int)(item.account.statusesCount%1000), item.account.statusesCount));
postsLabel.setText(getResources().getQuantityString(R.plurals.sk_posts_count_label, (int)(item.account.statusesCount%1000), item.account.statusesCount));
followersCount.setVisibility(item.account.followersCount < 0 ? View.GONE : View.VISIBLE);
followersLabel.setVisibility(item.account.followersCount < 0 ? View.GONE : View.VISIBLE);
followingCount.setVisibility(item.account.followingCount < 0 ? View.GONE : View.VISIBLE);
followingLabel.setVisibility(item.account.followingCount < 0 ? View.GONE : View.VISIBLE);
relationship=relationships.get(item.account.id);
if(relationship == null || !relationship.followedBy){
UiUtils.setExtraTextInfo(getContext(), null, findViewById(R.id.pronouns), true, false, false, item.account);
if(relationship==null || !relationship.followedBy){
actionWrap.setVisibility(View.GONE);
acceptWrap.setVisibility(View.VISIBLE);
rejectWrap.setVisibility(View.VISIBLE);
// i hate that i wasn't able to do this in xml
acceptButton.setCompoundDrawableTintList(acceptButton.getTextColors());
acceptProgress.setIndeterminateTintList(acceptButton.getTextColors());
rejectButton.setCompoundDrawableTintList(rejectButton.getTextColors());
rejectProgress.setIndeterminateTintList(rejectButton.getTextColors());
}else if(relationship==null){
actionWrap.setVisibility(View.GONE);
acceptWrap.setVisibility(View.GONE);
rejectWrap.setVisibility(View.GONE);
}else{
actionWrap.setVisibility(View.VISIBLE);
acceptWrap.setVisibility(View.GONE);

View File

@ -30,7 +30,6 @@ import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
import org.joinmastodon.android.ui.utils.DiscoverInfoBannerHelper;
import org.joinmastodon.android.ui.utils.InsetStatusItemDecoration;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.utils.ElevationOnScrollListener;
import org.joinmastodon.android.utils.ObjectIdComparator;
import org.parceler.Parcels;

View File

@ -197,7 +197,7 @@ public class DiscoverAccountsFragment extends MastodonRecyclerFragment<DiscoverA
}
}
private class AccountViewHolder extends BindableViewHolder<AccountWrapper> implements ImageLoaderViewHolder, UsableRecyclerView.Clickable{
private class AccountViewHolder extends BindableViewHolder<AccountWrapper> implements ImageLoaderViewHolder, UsableRecyclerView.DisableableClickable{
private final ImageView cover, avatar;
private final TextView name, username, bio, followersCount, followingCount, postsCount, followersLabel, followingLabel, postsLabel;
private final ProgressBarButton actionButton;
@ -223,13 +223,22 @@ public class DiscoverAccountsFragment extends MastodonRecyclerFragment<DiscoverA
actionProgress=findViewById(R.id.action_progress);
actionWrap=findViewById(R.id.action_btn_wrap);
itemView.setOutlineProvider(OutlineProviders.roundedRect(6));
itemView.setClipToOutline(true);
avatar.setOutlineProvider(OutlineProviders.roundedRect(12));
avatar.setOutlineProvider(OutlineProviders.roundedRect(15));
avatar.setClipToOutline(true);
cover.setOutlineProvider(OutlineProviders.roundedRect(3));
View border=findViewById(R.id.avatar_border);
border.setOutlineProvider(OutlineProviders.roundedRect(17));
border.setClipToOutline(true);
cover.setOutlineProvider(OutlineProviders.roundedRect(9));
cover.setClipToOutline(true);
itemView.setOutlineProvider(OutlineProviders.roundedRect(12));
itemView.setClipToOutline(true);
actionButton.setOnClickListener(this::onActionButtonClick);
itemView.setOnClickListener(v->this.onClick());
}
@Override
public boolean isEnabled(){
return false;
}
@Override
@ -242,12 +251,14 @@ public class DiscoverAccountsFragment extends MastodonRecyclerFragment<DiscoverA
postsCount.setText(UiUtils.abbreviateNumber(item.account.statusesCount));
followersLabel.setText(getResources().getQuantityString(R.plurals.followers, (int)Math.min(999, item.account.followersCount)));
followingLabel.setText(getResources().getQuantityString(R.plurals.following, (int)Math.min(999, item.account.followingCount)));
postsLabel.setText(getResources().getQuantityString(R.plurals.x_posts, (int)(item.account.statusesCount%1000), item.account.statusesCount));
postsLabel.setText(getResources().getQuantityString(R.plurals.sk_posts_count_label, (int)(item.account.statusesCount%1000), item.account.statusesCount));
followersCount.setVisibility(item.account.followersCount < 0 ? View.GONE : View.VISIBLE);
followersLabel.setVisibility(item.account.followersCount < 0 ? View.GONE : View.VISIBLE);
followingCount.setVisibility(item.account.followingCount < 0 ? View.GONE : View.VISIBLE);
followingLabel.setVisibility(item.account.followingCount < 0 ? View.GONE : View.VISIBLE);
relationship=relationships.get(item.account.id);
UiUtils.setExtraTextInfo(getContext(), null, findViewById(R.id.pronouns), true, false, false, item.account);
if(relationship==null){
actionWrap.setVisibility(View.GONE);
}else{

View File

@ -111,15 +111,24 @@ public class AccountCardStatusDisplayItem extends StatusDisplayItem{
rejectWrap=findViewById(R.id.reject_btn_wrap);
View card=findViewById(R.id.card);
card.setOutlineProvider(OutlineProviders.roundedRect(6));
card.setOutlineProvider(OutlineProviders.roundedRect(12));
card.setClipToOutline(true);
avatar.setOutlineProvider(OutlineProviders.roundedRect(12));
avatar.setOutlineProvider(OutlineProviders.roundedRect(15));
avatar.setClipToOutline(true);
cover.setOutlineProvider(OutlineProviders.roundedRect(3));
View border=findViewById(R.id.avatar_border);
border.setOutlineProvider(OutlineProviders.roundedRect(17));
border.setClipToOutline(true);
cover.setOutlineProvider(OutlineProviders.roundedRect(9));
cover.setClipToOutline(true);
actionButton.setOnClickListener(this::onActionButtonClick);
acceptButton.setOnClickListener(this::onFollowRequestButtonClick);
rejectButton.setOnClickListener(this::onFollowRequestButtonClick);
card.setOnClickListener(v->onClick());
}
@Override
public boolean isEnabled(){
return false;
}
@Override
@ -132,18 +141,19 @@ public class AccountCardStatusDisplayItem extends StatusDisplayItem{
postsCount.setText(UiUtils.abbreviateNumber(item.account.statusesCount));
followersLabel.setText(item.parentFragment.getResources().getQuantityString(R.plurals.followers, (int)Math.min(999, item.account.followersCount)));
followingLabel.setText(item.parentFragment.getResources().getQuantityString(R.plurals.following, (int)Math.min(999, item.account.followingCount)));
postsLabel.setText(item.parentFragment.getResources().getQuantityString(R.plurals.x_posts, (int)(item.account.statusesCount%1000), item.account.statusesCount));
postsLabel.setText(item.parentFragment.getResources().getQuantityString(R.plurals.sk_posts_count_label, (int)(item.account.statusesCount%1000), item.account.statusesCount));
followersCount.setVisibility(item.account.followersCount < 0 ? View.GONE : View.VISIBLE);
followersLabel.setVisibility(item.account.followersCount < 0 ? View.GONE : View.VISIBLE);
followingCount.setVisibility(item.account.followingCount < 0 ? View.GONE : View.VISIBLE);
followingLabel.setVisibility(item.account.followingCount < 0 ? View.GONE : View.VISIBLE);
relationship=item.parentFragment.getRelationship(item.account.id);
if(item.notification.type == Notification.Type.FOLLOW_REQUEST && (relationship == null || !relationship.followedBy)){
UiUtils.setExtraTextInfo(item.parentFragment.getContext(), null, findViewById(R.id.pronouns), true, false, false, item.account);
if(item.notification.type==Notification.Type.FOLLOW_REQUEST && (relationship==null || !relationship.followedBy)){
actionWrap.setVisibility(View.GONE);
acceptWrap.setVisibility(View.VISIBLE);
rejectWrap.setVisibility(View.VISIBLE);
// i hate that i wasn't able to do this in xml
acceptButton.setCompoundDrawableTintList(acceptButton.getTextColors());
acceptProgress.setIndeterminateTintList(acceptButton.getTextColors());
rejectButton.setCompoundDrawableTintList(rejectButton.getTextColors());
@ -163,7 +173,7 @@ public class AccountCardStatusDisplayItem extends StatusDisplayItem{
private void onFollowRequestButtonClick(View v) {
itemView.setHasTransientState(true);
UiUtils.handleFollowRequest((Activity) v.getContext(), item.account, item.parentFragment.getAccountID(), null, v == acceptButton, relationship, rel -> {
if(v.getContext()==null) return;
if(v.getContext()==null || rel==null) return;
itemView.setHasTransientState(false);
item.parentFragment.putRelationship(item.account.id, rel);
RecyclerView.Adapter<? extends RecyclerView.ViewHolder> adapter = getBindingAdapter();

View File

@ -8,8 +8,6 @@ import android.view.View;
import org.joinmastodon.android.R;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.ui.displayitems.LinkCardStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.MediaGridStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
import java.util.List;
@ -89,10 +87,10 @@ public class InsetStatusItemDecoration extends RecyclerView.ItemDecoration{
pad=V.dp(16);
// else
// pad=V.dp(12);
boolean insetLeft=true, insetRight=true;
if(insetLeft)
boolean insetPadding=((StatusDisplayItem.Holder<?>) holder).getItem().insetPadding;
if(insetPadding)
outRect.left=pad;
if(insetRight)
if(insetPadding)
outRect.right=pad;
// had to comment this out because animations with offsets aren't handled properly.

View File

@ -1073,8 +1073,8 @@ public class UiUtils {
return back;
}
public static boolean setExtraTextInfo(Context ctx, TextView extraText, TextView pronouns, boolean displayPronouns, boolean mentionedOnly, boolean localOnly, @Nullable Account account) {
List<String> extraParts = new ArrayList<>();
public static boolean setExtraTextInfo(Context ctx, @Nullable TextView extraText, @Nullable TextView pronouns, boolean displayPronouns, boolean mentionedOnly, boolean localOnly, @Nullable Account account) {
List<String> extraParts = extraText!=null && (localOnly || mentionedOnly) ? new ArrayList<>() : null;
Optional<String> p=pronouns==null || !displayPronouns ? Optional.empty() : extractPronouns(ctx, account);
if(p.isPresent()) {
HtmlParser.setTextWithCustomEmoji(pronouns, p.get(), account.emojis);
@ -1086,7 +1086,7 @@ public class UiUtils {
extraParts.add(ctx.getString(R.string.sk_inline_local_only));
if(mentionedOnly)
extraParts.add(ctx.getString(R.string.sk_inline_direct));
if(!extraParts.isEmpty()) {
if(extraText!=null && extraParts!=null && !extraParts.isEmpty()) {
String sepp = ctx.getString(R.string.sk_separator);
String text = String.join(" " + sepp + " ", extraParts);
if(account == null) extraText.setText(text);
@ -1094,7 +1094,7 @@ public class UiUtils {
extraText.setVisibility(View.VISIBLE);
return true;
}else{
extraText.setVisibility(View.GONE);
if(extraText!=null) extraText.setVisibility(View.GONE);
return false;
}
}

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<color android:color="?colorM3Surface"/>
</item>
<item>
<shape android:tint="?colorM3Primary">
<solid android:color="?colorFilledCardAlpha"/>
</shape>
</item>
<item>
<ripple android:color="@color/m3_on_surface_variant_overlay">
<item android:id="@android:id/mask">
<shape>
<solid android:color="#000"/>
<corners android:radius="4dp"/>
</shape>
</item>
</ripple>
</item>
</layer-list>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="26dp"/>
<stroke android:width="4dp" android:color="?colorM3Surface"/>
</shape>

View File

@ -3,74 +3,114 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorM3SurfaceVariant"
android:elevation="2dp"
android:paddingBottom="0dp">
android:background="@drawable/bg_filled_card">
<ImageView
android:id="@+id/cover"
android:layout_width="match_parent"
android:layout_height="128dp"
android:layout_marginTop="4dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginTop="6dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:scaleType="centerCrop"
tools:src="#0f0"/>
<View
android:id="@+id/avatar_border"
android:layout_width="60dp"
android:layout_height="60dp"
<FrameLayout
android:id="@+id/avatar_wrap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/cover"
android:layout_alignParentStart="true"
android:layout_marginTop="-6dp"
android:layout_marginStart="14dp"
android:background="@drawable/discover_ava_bg"/>
android:layout_marginTop="-12dp"
android:layout_marginStart="13dp"
android:layout_marginEnd="12dp">
<ImageView
android:id="@+id/avatar"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_below="@id/cover"
android:layout_alignParentStart="true"
android:layout_marginStart="16dp"
android:layout_marginTop="-4dp"
android:scaleType="centerCrop"
tools:src="#f00" />
<View
android:id="@+id/avatar_border"
android:layout_gravity="center"
android:layout_width="66dp"
android:layout_height="66dp"
android:background="@drawable/bg_filled_card"/>
<TextView
android:id="@+id/name"
<ImageView
android:id="@+id/avatar"
android:layout_gravity="center"
android:layout_width="60dp"
android:layout_height="60dp"
android:scaleType="centerCrop"
tools:src="#f00" />
</FrameLayout>
<org.joinmastodon.android.ui.views.HeaderSubtitleLinearLayout
android:id="@+id/name_wrap"
android:layout_width="match_parent"
android:layout_height="24dp"
android:layout_toEndOf="@id/avatar"
android:layout_below="@id/cover"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/avatar_wrap"
android:layout_marginEnd="16dp"
android:singleLine="true"
android:ellipsize="end"
android:gravity="center_vertical"
android:textAppearance="@style/m3_title_medium"
tools:text="Eugen"/>
android:layout_above="@+id/username">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="@style/m3_title_medium"
android:textColor="?colorM3OnSurface"
android:gravity="start|center_vertical"
tools:text="Eugen" />
<TextView
android:id="@+id/pronouns"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8sp"
android:maxWidth="161sp"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="@style/m3_title_medium"
android:fontFamily="sans-serif"
android:textAlignment="viewStart"
android:textColor="?colorM3OnSurface"
tools:text="they/them" />
<TextView
android:id="@+id/extra_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8sp"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="@style/m3_title_medium"
android:fontFamily="sans-serif"
android:textAlignment="viewStart"
android:textColor="?colorM3OnSurface"
tools:text="boosted your cat picture" />
</org.joinmastodon.android.ui.views.HeaderSubtitleLinearLayout>
<TextView
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignStart="@id/name"
android:layout_alignEnd="@id/name"
android:layout_below="@id/name"
android:layout_alignBottom="@id/avatar_wrap"
android:layout_marginEnd="16dp"
android:layout_toEndOf="@id/avatar_wrap"
android:layout_marginBottom="3sp"
android:textAlignment="viewStart"
android:singleLine="true"
android:ellipsize="end"
android:gravity="center_vertical"
android:textAppearance="@style/m3_title_small"
android:textAppearance="@style/m3_body_medium"
android:textColor="?colorM3OnSurfaceVariant"
tools:text="\@Gargron@mastodon.social"/>
<TextView
android:id="@+id/bio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/avatar"
android:layout_below="@id/avatar_wrap"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"

View File

@ -40,7 +40,7 @@
<color name="m3_neutral2_100">@android:color/system_neutral2_100</color>
<color name="m3_neutral2_50t">@android:color/system_neutral2_50</color>
<color name="m3_neutral2_50">@android:color/system_neutral2_50</color>
<color name="m3_neutral2_25">@android:color/system_neutral2_10</color>
<color name="m3_neutral2_10">@android:color/system_neutral2_10</color>
<color name="m3_accent2_25">@android:color/system_accent2_10</color>
<color name="m3_accent2_50">@android:color/system_accent2_50</color>

View File

@ -35,6 +35,7 @@
<attr name="colorProfileHeaderBackground" format="color"/>
<attr name="colorM3DarkOnSurface" format="color" />
<attr name="colorTabBarAlpha" format="color" />
<attr name="colorFilledCardAlpha" format="color" />
<attr name="colorPrimary25" format="color" />
<attr name="colorPrimary50" format="color" />

View File

@ -125,7 +125,7 @@
<color name="m3_neutral2_100">@color/gray_100</color>
<color name="m3_neutral2_50t">@color/gray_50t</color>
<color name="m3_neutral2_50">@color/gray_50</color>
<color name="m3_neutral2_25">@color/gray_25</color>
<color name="m3_neutral2_10">@color/gray_25</color>
<color name="m3_accent1_25">@color/primary_25</color>
<color name="m3_accent1_50">@color/primary_50</color>

View File

@ -28,6 +28,7 @@
</style>
<style name="ColorPalette">
<!-- https://m3.material.io/styles/color/the-color-system/tokens -->
<item name="colorM3Primary">?colorPrimary600</item>
<item name="colorM3OnPrimary">@color/white</item>
<item name="colorM3PrimaryContainer">?colorPrimary100</item>
@ -56,6 +57,7 @@
<item name="colorBoost">?colorM3Primary</item>
<item name="colorPoll">@color/bookmark_selected</item>
<item name="colorTabBarAlpha">#14000000</item>
<item name="colorFilledCardAlpha">#30000000</item>
<item name="colorM3DisabledBackground">#1F1F1F1F</item>
<item name="colorM3Error">#B3261E</item>
@ -151,6 +153,7 @@
<item name="colorM3SurfaceVariant">?colorNeutral900</item>
<item name="colorM3SecondaryContainer">?colorNeutral800</item>
<item name="colorTabBarAlpha">#00000000</item>
<item name="colorFilledCardAlpha">#00000000</item>
</style>
<style name="ColorPalette.Material3">
@ -238,7 +241,7 @@
<item name="colorNeutral100">@color/m3_neutral2_100</item>
<item name="colorNeutral50t">@color/m3_neutral2_50t</item>
<item name="colorNeutral50">@color/m3_neutral2_50</item>
<item name="colorNeutral25">@color/m3_neutral2_25</item>
<item name="colorNeutral25">@color/m3_neutral2_10</item>
</style>
<style name="ColorPalette.Material3.Dark">

View File

@ -372,4 +372,8 @@
<string name="sk_duration_days_3">3 days</string>
<string name="sk_duration_days_7">7 days</string>
<string name="sk_notification_mention">You were mentioned by %s</string>
<plurals name="sk_posts_count_label">
<item quantity="one">post</item>
<item quantity="other">posts</item>
</plurals>
</resources>