CultureQuestORG/SDP2023

View on GitHub
app/src/main/java/ch/epfl/culturequest/ui/leaderboard/LeaderboardRecycleViewAdapter.java

Summary

Maintainability
A
0 mins
Test Coverage
B
86%
package ch.epfl.culturequest.ui.leaderboard;


import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.squareup.picasso.Picasso;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import ch.epfl.culturequest.R;
import ch.epfl.culturequest.social.Profile;
import ch.epfl.culturequest.ui.events.tournaments.TournamentViewModel;
import ch.epfl.culturequest.ui.profile.DisplayUserProfileActivity;
import ch.epfl.culturequest.utils.ProfileUtils;
import de.hdodenhof.circleimageview.CircleImageView;

/**
 * Adapter for the Leaderboard RecyclerView that displays the top N users
 */
public class LeaderboardRecycleViewAdapter extends RecyclerView.Adapter<LeaderboardRecycleViewAdapter.LeaderboardViewHolder> {
    private List<String> topNUserNames;

    private List<String> topNUids;
    private List<String> topNUserScores;

    private List<String> topNUserRanks;

    private List<String> topNUserProfilePicturesUri;

    /**
     * Provide a reference to the type of view we are using for each
     * leaderboard item
     */
    public static class LeaderboardViewHolder extends RecyclerView.ViewHolder {
        private final TextView userName;
        private final TextView userScore;
        private final TextView userRank;
        private final CircleImageView userProfilePicture;

        public LeaderboardViewHolder(View leaderboardItemView) {
            super(leaderboardItemView);
            userName = leaderboardItemView.findViewById(R.id.username);
            userScore = leaderboardItemView.findViewById(R.id.user_score);
            userRank = leaderboardItemView.findViewById(R.id.user_rank);
            userProfilePicture = leaderboardItemView.findViewById(R.id.user_profile_picture);
        }

        public TextView getUserName() {
            return userName;
        }

        public TextView getUserScore() {
            return userScore;
        }

        public TextView getUserRank() {
            return userRank;
        }

        public CircleImageView getUserProfilePicture() {
            return userProfilePicture;
        }
    }

    /**
     * Initialize the dataset of the Adapter by observing the LiveData of the ViewModel
     * and updating the dataset when the LiveData is updated.
     *
     * @param leaderboardViewModel the ViewModel that contains the data to be displayed
     */
    public LeaderboardRecycleViewAdapter(LeaderboardViewModel leaderboardViewModel, LeaderboardFragment.Mode selectedMode) {
        switch (selectedMode) {
            case GLOBAL:
                leaderboardViewModel.getTopNUserNames().observeForever(topNUserNames -> {
                    this.topNUserNames = topNUserNames;
                    notifyItemRangeChanged(0, getItemCount());
                });

                leaderboardViewModel.getTopNUserUids().observeForever(topNUids ->{
                    this.topNUids = topNUids;
                    notifyItemRangeChanged(0, getItemCount());
                });

                leaderboardViewModel.getTopNUserScores().observeForever(topNUserScores -> {
                    this.topNUserScores = topNUserScores;
                    notifyItemRangeChanged(0, getItemCount());
                });
                leaderboardViewModel.getTopNUserRanks().observeForever(topNUserRanks -> {
                    this.topNUserRanks = topNUserRanks;
                    notifyItemRangeChanged(0, getItemCount());
                });
                leaderboardViewModel.getTopNUserProfilePicturesUri().observeForever(topNUserProfilePicturesUri -> {
                    this.topNUserProfilePicturesUri = topNUserProfilePicturesUri;
                    notifyItemRangeChanged(0, getItemCount());
                });
                break;
            case FRIENDS:
                leaderboardViewModel.getTopNUserNamesFriends().observeForever(topNUserNames -> {
                    this.topNUserNames = topNUserNames;
                    notifyItemRangeChanged(0, getItemCount());
                });

                leaderboardViewModel.getTopNUserUidsFriends().observeForever(topNUids ->{
                    this.topNUids = topNUids;
                    notifyItemRangeChanged(0, getItemCount());
                });

                leaderboardViewModel.getTopNUserScoresFriends().observeForever(topNUserScores -> {
                    this.topNUserScores = topNUserScores;
                    notifyItemRangeChanged(0, getItemCount());
                });
                leaderboardViewModel.getTopNUserRanksFriends().observeForever(topNUserRanks -> {
                    this.topNUserRanks = topNUserRanks;
                    notifyItemRangeChanged(0, getItemCount());
                });
                leaderboardViewModel.getTopNUserProfilePicturesUriFriends().observeForever(topNUserProfilePicturesUri -> {
                    this.topNUserProfilePicturesUri = topNUserProfilePicturesUri;
                    notifyItemRangeChanged(0, getItemCount());
                });
                break;

        }
    }

    public LeaderboardRecycleViewAdapter(TournamentViewModel tournamentViewModel) {
        tournamentViewModel.getTournamentLeaderboard().observeForever(v -> {
            this.topNUserNames = v.stream().map(x -> x.getKey().getName()).collect(Collectors.toList());
            this.topNUids = v.stream().map(x -> x.getKey().getUid()).collect(Collectors.toList());
            this.topNUserScores = v.stream().map(x -> x.getValue().toString()).collect(Collectors.toList());
            this.topNUserRanks = Stream.iterate(1, i -> i + 1).limit(v.size()).map(i -> Integer.toString(i)).collect(Collectors.toList());
            this.topNUserProfilePicturesUri = v.stream().map(x -> x.getKey().getProfilePicture()).collect(Collectors.toList());
            notifyItemRangeChanged(0, getItemCount());
        });
    }


    // Create new views (invoked by the layout manager)
    @NonNull
    @Override
    public LeaderboardViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        // Create a new view, which defines the UI of the leaderboard items
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.leaderboard_item, viewGroup, false);
        return new LeaderboardViewHolder(view);
    }

    // Replace the contents of a view when data changed (invoked by the layout manager)
    @Override
    public void onBindViewHolder(LeaderboardViewHolder leaderboardViewHolder, final int position) {
        Context itemViewContext = leaderboardViewHolder.itemView.getContext();
        List.of(leaderboardViewHolder.userName, leaderboardViewHolder.userProfilePicture).forEach(view -> {
            view.setOnClickListener(l -> {
                Intent intent = new Intent(itemViewContext, DisplayUserProfileActivity.class);
                intent.putExtra("uid", topNUids.get(position));
                itemViewContext.startActivity(intent);
            });
        });
        // Get element at this position and replace the contents of the view with that element
        leaderboardViewHolder.getUserName().setText(topNUserNames.get(position));
        leaderboardViewHolder.getUserScore().setText(topNUserScores.get(position));
        leaderboardViewHolder.getUserRank().setText(topNUserRanks.get(position));
        Picasso.get().load(topNUserProfilePicturesUri.get(position)).into(leaderboardViewHolder.getUserProfilePicture());

    }

    // Return the size of your dataset (invoked by the layout manager)
    // The size of the dataset is the minimum size of the lists of the top N users
    // (because the lists are updated asynchronously)
    @Override
    public int getItemCount() {
        if (topNUserNames == null || topNUserScores == null || topNUserRanks == null || topNUserProfilePicturesUri == null || topNUids == null) {
            return 0;
        } else {
            // return the minimum size of the lists
            return Math.min(topNUids.size(), Math.min(Math.min(topNUserNames.size(), topNUserScores.size()), Math.min(topNUserRanks.size(), topNUserProfilePicturesUri.size())));
        }
    }

}