From 351942ecd95fc075bbb03988f32e69edf3ae80bb Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Fri, 29 Nov 2024 11:08:43 -0600 Subject: [PATCH] Convert LeaderboardListAdapter to kotlin --- ...Constants.java => LeaderboardConstants.kt} | 20 ++- .../profile/leaderboard/LeaderboardList.java | 137 ------------------ .../profile/leaderboard/LeaderboardList.kt | 61 ++++++++ .../leaderboard/LeaderboardListAdapter.java | 93 ------------ .../leaderboard/LeaderboardListAdapter.kt | 64 ++++++++ 5 files changed, 134 insertions(+), 241 deletions(-) rename app/src/main/java/fr/free/nrw/commons/profile/leaderboard/{LeaderboardConstants.java => LeaderboardConstants.kt} (64%) delete mode 100644 app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardList.java create mode 100644 app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardList.kt delete mode 100644 app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardListAdapter.java create mode 100644 app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardListAdapter.kt diff --git a/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardConstants.java b/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardConstants.kt similarity index 64% rename from app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardConstants.java rename to app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardConstants.kt index 800287f4f..61776ee20 100644 --- a/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardConstants.java +++ b/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardConstants.kt @@ -1,45 +1,43 @@ -package fr.free.nrw.commons.profile.leaderboard; +package fr.free.nrw.commons.profile.leaderboard /** * This class contains the constant variables for leaderboard */ -public class LeaderboardConstants { - +object LeaderboardConstants { /** * This is the size of the page i.e. number items to load in a batch when pagination is performed */ - public static final int PAGE_SIZE = 100; + const val PAGE_SIZE: Int = 100 /** * This is the starting offset, we set it to 0 to start loading from rank 1 */ - public static final int START_OFFSET = 0; + const val START_OFFSET: Int = 0 /** * This is the prefix of the user's homepage url, appending the username will give us complete url */ - public static final String USER_LINK_PREFIX = "https://commons.wikimedia.org/wiki/User:"; + const val USER_LINK_PREFIX: String = "https://commons.wikimedia.org/wiki/User:" /** * This is the a constant string for the state loading, when the pages are getting loaded we can * use this constant to identify if we need to show the progress bar or not */ - public final static String LOADING = "Loading"; + const val LOADING: String = "Loading" /** * This is the a constant string for the state loaded, when the pages are loaded we can * use this constant to identify if we need to show the progress bar or not */ - public final static String LOADED = "Loaded"; + const val LOADED: String = "Loaded" /** * This API endpoint is to update the leaderboard avatar */ - public final static String UPDATE_AVATAR_END_POINT = "/update_avatar.py"; + const val UPDATE_AVATAR_END_POINT: String = "/update_avatar.py" /** * This API endpoint is to get leaderboard data */ - public final static String LEADERBOARD_END_POINT = "/leaderboard.py"; - + const val LEADERBOARD_END_POINT: String = "/leaderboard.py" } diff --git a/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardList.java b/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardList.java deleted file mode 100644 index 5558f3d9e..000000000 --- a/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardList.java +++ /dev/null @@ -1,137 +0,0 @@ -package fr.free.nrw.commons.profile.leaderboard; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.DiffUtil; -import androidx.recyclerview.widget.DiffUtil.ItemCallback; -import com.google.gson.annotations.Expose; -import com.google.gson.annotations.SerializedName; - -/** - * This class represents the leaderboard API response sub part of i.e. leaderboard list - * The leaderboard list will contain the ranking of the users from 1 to n, - * avatars, username and count in the selected category. - */ -public class LeaderboardList { - - /** - * Username of the user - * Example value - Syced - */ - @SerializedName("username") - @Expose - private String username; - - /** - * Count in the category - * Example value - 10 - */ - @SerializedName("category_count") - @Expose - private Integer categoryCount; - - /** - * URL of the avatar of user - * Example value = https://upload.wikimedia.org/wikipedia/commons/thumb/0/0a/Gnome-stock_person.svg/200px-Gnome-stock_person.svg.png - */ - @SerializedName("avatar") - @Expose - private String avatar; - - /** - * Rank of the user - * Example value - 1 - */ - @SerializedName("rank") - @Expose - private Integer rank; - - /** - * @return the username of the user in the leaderboard list - */ - public String getUsername() { - return username; - } - - /** - * Sets the username of the user in the leaderboard list - */ - public void setUsername(String username) { - this.username = username; - } - - /** - * @return the category count of the user in the leaderboard list - */ - public Integer getCategoryCount() { - return categoryCount; - } - - /** - * Sets the category count of the user in the leaderboard list - */ - public void setCategoryCount(Integer categoryCount) { - this.categoryCount = categoryCount; - } - - /** - * @return the avatar of the user in the leaderboard list - */ - public String getAvatar() { - return avatar; - } - - /** - * Sets the avatar of the user in the leaderboard list - */ - public void setAvatar(String avatar) { - this.avatar = avatar; - } - - /** - * @return the rank of the user in the leaderboard list - */ - public Integer getRank() { - return rank; - } - - /** - * Sets the rank of the user in the leaderboard list - */ - public void setRank(Integer rank) { - this.rank = rank; - } - - - /** - * This method checks for the diff in the callbacks for paged lists - */ - public static DiffUtil.ItemCallback DIFF_CALLBACK = - new ItemCallback() { - @Override - public boolean areItemsTheSame(@NonNull LeaderboardList oldItem, - @NonNull LeaderboardList newItem) { - return newItem == oldItem; - } - - @Override - public boolean areContentsTheSame(@NonNull LeaderboardList oldItem, - @NonNull LeaderboardList newItem) { - return newItem.getRank().equals(oldItem.getRank()); - } - }; - - /** - * Returns true if two objects are equal, false otherwise - * @param obj - * @return - */ - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - LeaderboardList leaderboardList = (LeaderboardList) obj; - return leaderboardList.getRank().equals(this.getRank()); - } -} \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardList.kt b/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardList.kt new file mode 100644 index 000000000..dc6d93e15 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardList.kt @@ -0,0 +1,61 @@ +package fr.free.nrw.commons.profile.leaderboard + +import androidx.recyclerview.widget.DiffUtil +import com.google.gson.annotations.SerializedName + +/** + * This class represents the leaderboard API response sub part of i.e. leaderboard list + * The leaderboard list will contain the ranking of the users from 1 to n, + * avatars, username and count in the selected category. + */ +data class LeaderboardList ( + @SerializedName("username") + var username: String? = null, + @SerializedName("category_count") + var categoryCount: Int? = null, + @SerializedName("avatar") + var avatar: String? = null, + @SerializedName("rank") + var rank: Int? = null +) { + + /** + * Returns true if two objects are equal, false otherwise + * @param other + * @return + */ + override fun equals(other: Any?): Boolean { + if (other === this) { + return true + } + + val leaderboardList = other as LeaderboardList + return leaderboardList.rank == rank + } + + override fun hashCode(): Int { + var result = username?.hashCode() ?: 0 + result = 31 * result + (categoryCount ?: 0) + result = 31 * result + (avatar?.hashCode() ?: 0) + result = 31 * result + (rank ?: 0) + return result + } + + companion object { + /** + * This method checks for the diff in the callbacks for paged lists + */ + var DIFF_CALLBACK: DiffUtil.ItemCallback = + object : DiffUtil.ItemCallback() { + override fun areItemsTheSame( + oldItem: LeaderboardList, + newItem: LeaderboardList + ): Boolean = newItem === oldItem + + override fun areContentsTheSame( + oldItem: LeaderboardList, + newItem: LeaderboardList + ): Boolean = newItem.rank == oldItem.rank + } + } +} \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardListAdapter.java b/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardListAdapter.java deleted file mode 100644 index 9af24159a..000000000 --- a/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardListAdapter.java +++ /dev/null @@ -1,93 +0,0 @@ -package fr.free.nrw.commons.profile.leaderboard; - - -import android.app.Activity; -import android.content.Context; -import android.net.Uri; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.paging.PagedListAdapter; -import androidx.recyclerview.widget.RecyclerView; -import com.facebook.drawee.view.SimpleDraweeView; -import fr.free.nrw.commons.R; -import fr.free.nrw.commons.profile.ProfileActivity; - -/** - * This class extends RecyclerView.Adapter and creates the List section of the leaderboard - */ -public class LeaderboardListAdapter extends PagedListAdapter { - - public LeaderboardListAdapter() { - super(LeaderboardList.DIFF_CALLBACK); - } - - public class ListViewHolder extends RecyclerView.ViewHolder { - TextView rank; - SimpleDraweeView avatar; - TextView username; - TextView count; - - public ListViewHolder(View itemView) { - super(itemView); - this.rank = itemView.findViewById(R.id.user_rank); - this.avatar = itemView.findViewById(R.id.user_avatar); - this.username = itemView.findViewById(R.id.user_name); - this.count = itemView.findViewById(R.id.user_count); - } - - /** - * This method will return the Context - * @return Context - */ - public Context getContext() { - return itemView.getContext(); - } - } - - /** - * Overrides the onCreateViewHolder and inflates the recyclerview list item layout - * @param parent - * @param viewType - * @return - */ - @NonNull - @Override - public LeaderboardListAdapter.ListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.leaderboard_list_element, parent, false); - - return new ListViewHolder(view); - } - - /** - * Overrides the onBindViewHolder Set the view at the specific position with the specific value - * @param holder - * @param position - */ - @Override - public void onBindViewHolder(@NonNull LeaderboardListAdapter.ListViewHolder holder, int position) { - TextView rank = holder.rank; - SimpleDraweeView avatar = holder.avatar; - TextView username = holder.username; - TextView count = holder.count; - - rank.setText(getItem(position).getRank().toString()); - - avatar.setImageURI(Uri.parse(getItem(position).getAvatar())); - username.setText(getItem(position).getUsername()); - count.setText(getItem(position).getCategoryCount().toString()); - - /* - Now that we have our in app profile-section, lets take the user there - */ - holder.itemView.setOnClickListener(view -> { - if (view.getContext() instanceof ProfileActivity) { - ((Activity) (view.getContext())).finish(); - } - ProfileActivity.startYourself(view.getContext(), getItem(position).getUsername(), true); - }); - } -} diff --git a/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardListAdapter.kt b/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardListAdapter.kt new file mode 100644 index 000000000..d181f5648 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardListAdapter.kt @@ -0,0 +1,64 @@ +package fr.free.nrw.commons.profile.leaderboard + +import android.app.Activity +import android.net.Uri +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.paging.PagedListAdapter +import androidx.recyclerview.widget.RecyclerView +import com.facebook.drawee.view.SimpleDraweeView +import fr.free.nrw.commons.R +import fr.free.nrw.commons.profile.ProfileActivity +import fr.free.nrw.commons.profile.leaderboard.LeaderboardList.Companion.DIFF_CALLBACK +import fr.free.nrw.commons.profile.leaderboard.LeaderboardListAdapter.ListViewHolder + + +/** + * This class extends RecyclerView.Adapter and creates the List section of the leaderboard + */ +class LeaderboardListAdapter : PagedListAdapter(DIFF_CALLBACK) { + inner class ListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + var rank: TextView = itemView.findViewById(R.id.user_rank) + var avatar: SimpleDraweeView = itemView.findViewById(R.id.user_avatar) + var username: TextView = itemView.findViewById(R.id.user_name) + var count: TextView = itemView.findViewById(R.id.user_count) + } + + /** + * Overrides the onCreateViewHolder and inflates the recyclerview list item layout + * @param parent + * @param viewType + * @return + */ + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder = + ListViewHolder( + LayoutInflater.from(parent.context) + .inflate(R.layout.leaderboard_list_element, parent, false) + ) + + /** + * Overrides the onBindViewHolder Set the view at the specific position with the specific value + * @param holder + * @param position + */ + override fun onBindViewHolder(holder: ListViewHolder, position: Int) = with (holder) { + val item = getItem(position)!! + + rank.text = item.rank.toString() + avatar.setImageURI(Uri.parse(item.avatar)) + username.text = item.username + count.text = item.categoryCount.toString() + + /* + Now that we have our in app profile-section, lets take the user there + */ + itemView.setOnClickListener { view: View -> + if (view.context is ProfileActivity) { + ((view.context) as Activity).finish() + } + ProfileActivity.startYourself(view.context, item.username, true) + } + } +}