Convert AccountViewHolder from Java to Kotlin (#3044)
* Convert AccountViewHolder from Java to Kotlin Use view binding in the converted code, which requires small changes in code that calls constructors. Pass showBotOverlays as a parameter, rather than having the code reach in to the shared preferences, fixing a layering violation. This affects callers and classes derived from AccountAdapter. * Use 2-arg getString * Simplify setting bot badge indicator - Specify the drawable in the XML - Use visible() to set visibility - Rename ID to account_bot_badge to make it clearer that this is all it is for * Use lateinit to avoid needing !! later
This commit is contained in:
parent
a21f2fadf9
commit
ee765a3117
13 changed files with 116 additions and 91 deletions
|
@ -26,7 +26,8 @@ import com.keylesspalace.tusky.util.removeDuplicates
|
|||
abstract class AccountAdapter<AVH : RecyclerView.ViewHolder> internal constructor(
|
||||
var accountActionListener: AccountActionListener,
|
||||
protected val animateAvatar: Boolean,
|
||||
protected val animateEmojis: Boolean
|
||||
protected val animateEmojis: Boolean,
|
||||
protected val showBotOverlay: Boolean
|
||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder?>() {
|
||||
var accountList = mutableListOf<TimelineAccount>()
|
||||
private var bottomLoading: Boolean = false
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
package com.keylesspalace.tusky.adapter;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.keylesspalace.tusky.R;
|
||||
import com.keylesspalace.tusky.entity.TimelineAccount;
|
||||
import com.keylesspalace.tusky.interfaces.AccountActionListener;
|
||||
import com.keylesspalace.tusky.interfaces.LinkListener;
|
||||
import com.keylesspalace.tusky.util.CustomEmojiHelper;
|
||||
import com.keylesspalace.tusky.util.ImageLoadingHelper;
|
||||
|
||||
public class AccountViewHolder extends RecyclerView.ViewHolder {
|
||||
private TextView username;
|
||||
private TextView displayName;
|
||||
private ImageView avatar;
|
||||
private ImageView avatarInset;
|
||||
private String accountId;
|
||||
private boolean showBotOverlay;
|
||||
|
||||
public AccountViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
username = itemView.findViewById(R.id.account_username);
|
||||
displayName = itemView.findViewById(R.id.account_display_name);
|
||||
avatar = itemView.findViewById(R.id.account_avatar);
|
||||
avatarInset = itemView.findViewById(R.id.account_avatar_inset);
|
||||
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(itemView.getContext());
|
||||
showBotOverlay = sharedPrefs.getBoolean("showBotOverlay", true);
|
||||
}
|
||||
|
||||
public void setupWithAccount(TimelineAccount account, boolean animateAvatar, boolean animateEmojis) {
|
||||
accountId = account.getId();
|
||||
String format = username.getContext().getString(R.string.post_username_format);
|
||||
String formattedUsername = String.format(format, account.getUsername());
|
||||
username.setText(formattedUsername);
|
||||
CharSequence emojifiedName = CustomEmojiHelper.emojify(account.getName(), account.getEmojis(), displayName, animateEmojis);
|
||||
displayName.setText(emojifiedName);
|
||||
int avatarRadius = avatar.getContext().getResources()
|
||||
.getDimensionPixelSize(R.dimen.avatar_radius_48dp);
|
||||
ImageLoadingHelper.loadAvatar(account.getAvatar(), avatar, avatarRadius, animateAvatar);
|
||||
if (showBotOverlay && account.getBot()) {
|
||||
avatarInset.setVisibility(View.VISIBLE);
|
||||
avatarInset.setImageResource(R.drawable.bot_badge);
|
||||
} else {
|
||||
avatarInset.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
void setupActionListener(final AccountActionListener listener) {
|
||||
itemView.setOnClickListener(v -> listener.onViewAccount(accountId));
|
||||
}
|
||||
|
||||
public void setupLinkListener(final LinkListener listener) {
|
||||
itemView.setOnClickListener(v -> listener.onViewAccount(accountId));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package com.keylesspalace.tusky.adapter
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.databinding.ItemAccountBinding
|
||||
import com.keylesspalace.tusky.entity.TimelineAccount
|
||||
import com.keylesspalace.tusky.interfaces.AccountActionListener
|
||||
import com.keylesspalace.tusky.interfaces.LinkListener
|
||||
import com.keylesspalace.tusky.util.emojify
|
||||
import com.keylesspalace.tusky.util.loadAvatar
|
||||
import com.keylesspalace.tusky.util.visible
|
||||
|
||||
class AccountViewHolder(
|
||||
private val binding: ItemAccountBinding
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
private lateinit var accountId: String
|
||||
|
||||
fun setupWithAccount(
|
||||
account: TimelineAccount,
|
||||
animateAvatar: Boolean,
|
||||
animateEmojis: Boolean,
|
||||
showBotOverlay: Boolean
|
||||
) {
|
||||
accountId = account.id
|
||||
|
||||
binding.accountUsername.text = binding.accountUsername.context.getString(
|
||||
R.string.post_username_format,
|
||||
account.username
|
||||
)
|
||||
|
||||
val emojifiedName = account.name.emojify(
|
||||
account.emojis,
|
||||
binding.accountDisplayName,
|
||||
animateEmojis
|
||||
)
|
||||
binding.accountDisplayName.text = emojifiedName
|
||||
|
||||
val avatarRadius = binding.accountAvatar.context.resources
|
||||
.getDimensionPixelSize(R.dimen.avatar_radius_48dp)
|
||||
loadAvatar(account.avatar, binding.accountAvatar, avatarRadius, animateAvatar)
|
||||
|
||||
binding.accountBotBadge.visible(showBotOverlay && account.bot)
|
||||
}
|
||||
|
||||
fun setupActionListener(listener: AccountActionListener) {
|
||||
itemView.setOnClickListener { listener.onViewAccount(accountId) }
|
||||
}
|
||||
|
||||
fun setupLinkListener(listener: LinkListener) {
|
||||
itemView.setOnClickListener {
|
||||
listener.onViewAccount(
|
||||
accountId
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -31,11 +31,13 @@ import com.keylesspalace.tusky.util.loadAvatar
|
|||
class BlocksAdapter(
|
||||
accountActionListener: AccountActionListener,
|
||||
animateAvatar: Boolean,
|
||||
animateEmojis: Boolean
|
||||
animateEmojis: Boolean,
|
||||
showBotOverlay: Boolean,
|
||||
) : AccountAdapter<BlocksAdapter.BlockedUserViewHolder>(
|
||||
accountActionListener,
|
||||
animateAvatar,
|
||||
animateEmojis
|
||||
animateEmojis,
|
||||
showBotOverlay
|
||||
) {
|
||||
override fun createAccountViewHolder(parent: ViewGroup): BlockedUserViewHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
|
|
|
@ -16,23 +16,37 @@ package com.keylesspalace.tusky.adapter
|
|||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.databinding.ItemAccountBinding
|
||||
import com.keylesspalace.tusky.interfaces.AccountActionListener
|
||||
|
||||
/** Displays either a follows or following list. */
|
||||
class FollowAdapter(
|
||||
accountActionListener: AccountActionListener,
|
||||
animateAvatar: Boolean,
|
||||
animateEmojis: Boolean
|
||||
) : AccountAdapter<AccountViewHolder>(accountActionListener, animateAvatar, animateEmojis) {
|
||||
animateEmojis: Boolean,
|
||||
showBotOverlay: Boolean
|
||||
) : AccountAdapter<AccountViewHolder>(
|
||||
accountActionListener,
|
||||
animateAvatar,
|
||||
animateEmojis,
|
||||
showBotOverlay
|
||||
) {
|
||||
override fun createAccountViewHolder(parent: ViewGroup): AccountViewHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_account, parent, false)
|
||||
return AccountViewHolder(view)
|
||||
val binding = ItemAccountBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
return AccountViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun onBindAccountViewHolder(viewHolder: AccountViewHolder, position: Int) {
|
||||
viewHolder.setupWithAccount(accountList[position], animateAvatar, animateEmojis)
|
||||
viewHolder.setupWithAccount(
|
||||
accountList[position],
|
||||
animateAvatar,
|
||||
animateEmojis,
|
||||
showBotOverlay
|
||||
)
|
||||
viewHolder.setupActionListener(accountActionListener)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,12 @@ class FollowRequestViewHolder(
|
|||
private val showHeader: Boolean
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
|
||||
fun setupWithAccount(account: TimelineAccount, animateAvatar: Boolean, animateEmojis: Boolean) {
|
||||
fun setupWithAccount(
|
||||
account: TimelineAccount,
|
||||
animateAvatar: Boolean,
|
||||
animateEmojis: Boolean,
|
||||
showBotOverlay: Boolean
|
||||
) {
|
||||
val wrappedName = account.name.unicodeWrap()
|
||||
val emojifiedName: CharSequence = wrappedName.emojify(account.emojis, itemView, animateEmojis)
|
||||
binding.displayNameTextView.text = emojifiedName
|
||||
|
|
|
@ -23,8 +23,9 @@ import com.keylesspalace.tusky.interfaces.AccountActionListener
|
|||
class FollowRequestsAdapter(
|
||||
accountActionListener: AccountActionListener,
|
||||
animateAvatar: Boolean,
|
||||
animateEmojis: Boolean
|
||||
) : AccountAdapter<FollowRequestViewHolder>(accountActionListener, animateAvatar, animateEmojis) {
|
||||
animateEmojis: Boolean,
|
||||
showBotOverlay: Boolean
|
||||
) : AccountAdapter<FollowRequestViewHolder>(accountActionListener, animateAvatar, animateEmojis, showBotOverlay) {
|
||||
override fun createAccountViewHolder(parent: ViewGroup): FollowRequestViewHolder {
|
||||
val binding = ItemFollowRequestBinding.inflate(
|
||||
LayoutInflater.from(parent.context), parent, false
|
||||
|
@ -33,7 +34,7 @@ class FollowRequestsAdapter(
|
|||
}
|
||||
|
||||
override fun onBindAccountViewHolder(viewHolder: FollowRequestViewHolder, position: Int) {
|
||||
viewHolder.setupWithAccount(accountList[position], animateAvatar, animateEmojis)
|
||||
viewHolder.setupWithAccount(accountList[position], animateAvatar, animateEmojis, showBotOverlay)
|
||||
viewHolder.setupActionListener(accountActionListener, accountList[position].id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ import com.keylesspalace.tusky.entity.TimelineAccount
|
|||
import com.keylesspalace.tusky.interfaces.AccountActionListener
|
||||
import com.keylesspalace.tusky.util.emojify
|
||||
import com.keylesspalace.tusky.util.loadAvatar
|
||||
import java.util.HashMap
|
||||
|
||||
/**
|
||||
* Displays a list of muted accounts with mute/unmute account and mute/unmute notifications
|
||||
|
@ -22,11 +21,13 @@ import java.util.HashMap
|
|||
class MutesAdapter(
|
||||
accountActionListener: AccountActionListener,
|
||||
animateAvatar: Boolean,
|
||||
animateEmojis: Boolean
|
||||
animateEmojis: Boolean,
|
||||
showBotOverlay: Boolean
|
||||
) : AccountAdapter<MutesAdapter.MutedUserViewHolder>(
|
||||
accountActionListener,
|
||||
animateAvatar,
|
||||
animateEmojis
|
||||
animateEmojis,
|
||||
showBotOverlay
|
||||
) {
|
||||
private val mutingNotificationsMap = HashMap<String, Boolean>()
|
||||
|
||||
|
|
|
@ -253,7 +253,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
|
|||
case VIEW_TYPE_FOLLOW_REQUEST: {
|
||||
if (payloadForHolder == null) {
|
||||
FollowRequestViewHolder holder = (FollowRequestViewHolder) viewHolder;
|
||||
holder.setupWithAccount(concreteNotification.getAccount(), statusDisplayOptions.animateAvatars(), statusDisplayOptions.animateEmojis());
|
||||
holder.setupWithAccount(concreteNotification.getAccount(), statusDisplayOptions.animateAvatars(), statusDisplayOptions.animateEmojis(), statusDisplayOptions.showBotOverlay());
|
||||
holder.setupActionListener(accountActionListener, concreteNotification.getAccount().getId());
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue