mirror of https://github.com/KokaKiwi/BarInsta
203 lines
7.7 KiB
Java
203 lines
7.7 KiB
Java
package awais.instagrabber.adapters;
|
|
|
|
import android.view.LayoutInflater;
|
|
import android.view.ViewGroup;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
import androidx.core.util.ObjectsCompat;
|
|
import androidx.recyclerview.widget.AdapterListUpdateCallback;
|
|
import androidx.recyclerview.widget.AsyncDifferConfig;
|
|
import androidx.recyclerview.widget.AsyncListDiffer;
|
|
import androidx.recyclerview.widget.DiffUtil;
|
|
import androidx.recyclerview.widget.RecyclerView;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
|
|
import awais.instagrabber.R;
|
|
import awais.instagrabber.adapters.viewholder.FavoriteViewHolder;
|
|
import awais.instagrabber.databinding.ItemFavSectionHeaderBinding;
|
|
import awais.instagrabber.databinding.ItemSearchResultBinding;
|
|
import awais.instagrabber.db.entities.Favorite;
|
|
import awais.instagrabber.models.enums.FavoriteType;
|
|
|
|
public class FavoritesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
|
|
|
private final OnFavoriteClickListener clickListener;
|
|
private final OnFavoriteLongClickListener longClickListener;
|
|
private final AsyncListDiffer<FavoriteModelOrHeader> differ;
|
|
|
|
private static final DiffUtil.ItemCallback<FavoriteModelOrHeader> diffCallback = new DiffUtil.ItemCallback<FavoriteModelOrHeader>() {
|
|
@Override
|
|
public boolean areItemsTheSame(@NonNull final FavoriteModelOrHeader oldItem, @NonNull final FavoriteModelOrHeader newItem) {
|
|
boolean areSame = oldItem.isHeader() && newItem.isHeader();
|
|
if (!areSame) {
|
|
return false;
|
|
}
|
|
if (oldItem.isHeader()) {
|
|
return ObjectsCompat.equals(oldItem.header, newItem.header);
|
|
}
|
|
if (oldItem.model != null && newItem.model != null) {
|
|
return oldItem.model.getId() == newItem.model.getId();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean areContentsTheSame(@NonNull final FavoriteModelOrHeader oldItem, @NonNull final FavoriteModelOrHeader newItem) {
|
|
boolean areSame = oldItem.isHeader() && newItem.isHeader();
|
|
if (!areSame) {
|
|
return false;
|
|
}
|
|
if (oldItem.isHeader()) {
|
|
return ObjectsCompat.equals(oldItem.header, newItem.header);
|
|
}
|
|
return ObjectsCompat.equals(oldItem.model, newItem.model);
|
|
}
|
|
};
|
|
|
|
public FavoritesAdapter(final OnFavoriteClickListener clickListener, final OnFavoriteLongClickListener longClickListener) {
|
|
this.clickListener = clickListener;
|
|
this.longClickListener = longClickListener;
|
|
differ = new AsyncListDiffer<>(new AdapterListUpdateCallback(this),
|
|
new AsyncDifferConfig.Builder<>(diffCallback).build());
|
|
}
|
|
|
|
@NonNull
|
|
@Override
|
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
|
|
final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
|
if (viewType == 0) {
|
|
// header
|
|
return new FavSectionViewHolder(ItemFavSectionHeaderBinding.inflate(inflater, parent, false));
|
|
}
|
|
final ItemSearchResultBinding binding = ItemSearchResultBinding.inflate(inflater, parent, false);
|
|
return new FavoriteViewHolder(binding);
|
|
}
|
|
|
|
@Override
|
|
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) {
|
|
if (getItemViewType(position) == 0) {
|
|
final FavoriteModelOrHeader modelOrHeader = getItem(position);
|
|
if (!modelOrHeader.isHeader()) return;
|
|
((FavSectionViewHolder) holder).bind(modelOrHeader.header);
|
|
return;
|
|
}
|
|
((FavoriteViewHolder) holder).bind(getItem(position).model, clickListener, longClickListener);
|
|
}
|
|
|
|
protected FavoriteModelOrHeader getItem(int position) {
|
|
return differ.getCurrentList().get(position);
|
|
}
|
|
|
|
@Override
|
|
public int getItemCount() {
|
|
return differ.getCurrentList().size();
|
|
}
|
|
|
|
@Override
|
|
public int getItemViewType(final int position) {
|
|
return getItem(position).isHeader() ? 0 : 1;
|
|
}
|
|
|
|
public void submitList(@Nullable final List<Favorite> list) {
|
|
if (list == null) {
|
|
differ.submitList(null);
|
|
return;
|
|
}
|
|
differ.submitList(sectionAndSort(list));
|
|
}
|
|
|
|
public void submitList(@Nullable final List<Favorite> list, @Nullable final Runnable commitCallback) {
|
|
if (list == null) {
|
|
differ.submitList(null, commitCallback);
|
|
return;
|
|
}
|
|
differ.submitList(sectionAndSort(list), commitCallback);
|
|
}
|
|
|
|
@NonNull
|
|
private List<FavoriteModelOrHeader> sectionAndSort(@NonNull final List<Favorite> list) {
|
|
final List<Favorite> listCopy = new ArrayList<>(list);
|
|
Collections.sort(listCopy, (o1, o2) -> {
|
|
if (o1.getType() == o2.getType()) return 0;
|
|
// keep users at top
|
|
if (o1.getType() == FavoriteType.USER) return -1;
|
|
if (o2.getType() == FavoriteType.USER) return 1;
|
|
// keep locations at bottom
|
|
if (o1.getType() == FavoriteType.LOCATION) return 1;
|
|
if (o2.getType() == FavoriteType.LOCATION) return -1;
|
|
return 0;
|
|
});
|
|
final List<FavoriteModelOrHeader> modelOrHeaders = new ArrayList<>();
|
|
for (int i = 0; i < listCopy.size(); i++) {
|
|
final Favorite model = listCopy.get(i);
|
|
final FavoriteModelOrHeader prev = modelOrHeaders.isEmpty() ? null : modelOrHeaders.get(modelOrHeaders.size() - 1);
|
|
boolean prevWasSameType = prev != null && prev.model.getType() == model.getType();
|
|
if (prevWasSameType) {
|
|
// just add model
|
|
final FavoriteModelOrHeader modelOrHeader = new FavoriteModelOrHeader();
|
|
modelOrHeader.model = model;
|
|
modelOrHeaders.add(modelOrHeader);
|
|
continue;
|
|
}
|
|
// add header and model
|
|
FavoriteModelOrHeader modelOrHeader = new FavoriteModelOrHeader();
|
|
modelOrHeader.header = model.getType();
|
|
modelOrHeaders.add(modelOrHeader);
|
|
modelOrHeader = new FavoriteModelOrHeader();
|
|
modelOrHeader.model = model;
|
|
modelOrHeaders.add(modelOrHeader);
|
|
}
|
|
return modelOrHeaders;
|
|
}
|
|
|
|
private static class FavoriteModelOrHeader {
|
|
FavoriteType header;
|
|
Favorite model;
|
|
|
|
boolean isHeader() {
|
|
return header != null;
|
|
}
|
|
}
|
|
|
|
public interface OnFavoriteClickListener {
|
|
void onClick(final Favorite model);
|
|
}
|
|
|
|
public interface OnFavoriteLongClickListener {
|
|
boolean onLongClick(final Favorite model);
|
|
}
|
|
|
|
public static class FavSectionViewHolder extends RecyclerView.ViewHolder {
|
|
private final ItemFavSectionHeaderBinding binding;
|
|
|
|
public FavSectionViewHolder(@NonNull final ItemFavSectionHeaderBinding binding) {
|
|
super(binding.getRoot());
|
|
this.binding = binding;
|
|
}
|
|
|
|
public void bind(final FavoriteType header) {
|
|
if (header == null) return;
|
|
final int headerText;
|
|
switch (header) {
|
|
case USER:
|
|
headerText = R.string.accounts;
|
|
break;
|
|
case HASHTAG:
|
|
headerText = R.string.hashtags;
|
|
break;
|
|
case LOCATION:
|
|
headerText = R.string.locations;
|
|
break;
|
|
default:
|
|
headerText = R.string.unknown;
|
|
break;
|
|
}
|
|
binding.getRoot().setText(headerText);
|
|
}
|
|
}
|
|
}
|