package pasta.music.adapters;
import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.graphics.Palette;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.afollestad.async.Action;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.GlideDrawableImageViewTarget;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import pasta.music.Pasta;
import pasta.music.R;
import pasta.music.activities.PlayerActivity;
import pasta.music.data.AlbumListData;
import pasta.music.data.ArtistListData;
import pasta.music.data.PlaylistListData;
import pasta.music.data.TrackListData;
import pasta.music.fragments.AlbumFragment;
import pasta.music.fragments.ArtistFragment;
import pasta.music.fragments.PlaylistFragment;
import pasta.music.utils.ImageUtils;
import pasta.music.utils.PreferenceUtils;
import pasta.music.utils.StaticUtils;
import pasta.music.views.CustomImageView;
public class SectionedOmniAdapter extends RecyclerView.Adapter<SectionedOmniAdapter.ViewHolder> {
private List<TrackListData> tracks;
private List<AlbumListData> albums;
private List<PlaylistListData> playlists;
private List<ArtistListData> artists;
private AppCompatActivity activity;
private List list;
private boolean thumbnails, cards, palette, dark;
private Pasta pasta;
public SectionedOmniAdapter(AppCompatActivity activity, ArrayList list) {
tracks = new ArrayList<>();
albums = new ArrayList<>();
playlists = new ArrayList<>();
artists = new ArrayList<>();
this.activity = activity;
pasta = (Pasta) activity.getApplicationContext();
thumbnails = PreferenceUtils.isThumbnails(activity);
cards = PreferenceUtils.isCards(activity);
palette = PreferenceUtils.isPalette(activity);
dark = PreferenceUtils.isDarkTheme(activity);
if (list == null) {
this.list = new ArrayList();
return;
}
this.list = list;
for (Object o : list) {
if (o instanceof TrackListData) tracks.add((TrackListData) o);
else if (o instanceof AlbumListData) albums.add((AlbumListData) o);
else if (o instanceof PlaylistListData) playlists.add((PlaylistListData) o);
else if (o instanceof ArtistListData) artists.add((ArtistListData) o);
}
}
public void addData(Parcelable data) {
int pos, offset;
if (data instanceof TrackListData) {
pos = tracks.size();
offset = 1;
tracks.add((TrackListData) data);
} else if (data instanceof AlbumListData) {
pos = tracks.size() + albums.size();
offset = 2;
albums.add((AlbumListData) data);
} else if (data instanceof PlaylistListData) {
pos = tracks.size() + albums.size() + playlists.size();
offset = 3;
playlists.add((PlaylistListData) data);
} else if (data instanceof ArtistListData) {
pos = tracks.size() + albums.size() + playlists.size() + artists.size();
offset = 4;
artists.add((ArtistListData) data);
} else {
return;
}
list.add(pos, data);
notifyItemInserted(pos + offset);
}
public void addData(List datas) {
datas.addAll(list);
swapData(datas);
}
public void swapData(List list) {
this.list = list;
tracks.clear();
albums.clear();
playlists.clear();
artists.clear();
for (Object o : list) {
if (o instanceof TrackListData) tracks.add((TrackListData) o);
else if (o instanceof AlbumListData) albums.add((AlbumListData) o);
else if (o instanceof PlaylistListData) playlists.add((PlaylistListData) o);
else if (o instanceof ArtistListData) artists.add((ArtistListData) o);
}
Collections.sort(list, new Comparator() {
@Override
public int compare(Object lhs, Object rhs) {
int comparison = 0;
if (lhs instanceof TrackListData) comparison += 1;
else if (lhs instanceof AlbumListData) comparison += 2;
else if (lhs instanceof PlaylistListData) comparison += 3;
else if (lhs instanceof ArtistListData) comparison += 4;
if (rhs instanceof TrackListData) comparison -= 1;
else if (rhs instanceof AlbumListData) comparison -= 2;
else if (rhs instanceof PlaylistListData) comparison -= 3;
else if (rhs instanceof ArtistListData) comparison -= 4;
return comparison;
}
});
notifyDataSetChanged();
}
public void clear() {
list.clear();
tracks.clear();
albums.clear();
playlists.clear();
artists.clear();
notifyDataSetChanged();
}
@Override
public int getItemViewType(int position) {
if (getAbsPosition(position) < 0) return 4;
Object o = list.get(getAbsPosition(position));
if (o instanceof TrackListData) return 0;
else if (o instanceof AlbumListData) return 1;
else if (o instanceof PlaylistListData) return 2;
else if (o instanceof ArtistListData) return 3;
else return 4;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
switch (viewType) {
case 0:
return new TrackViewHolder(inflater.inflate(R.layout.track_item, null));
case 1:
return new AlbumViewHolder(inflater.inflate(cards ? R.layout.album_item_card : R.layout.album_item_tile, null));
case 2:
return new PlaylistViewHolder(inflater.inflate(cards ? R.layout.playlist_item_card : R.layout.playlist_item_tile, null));
case 3:
return new ArtistViewHolder(inflater.inflate(cards ? R.layout.artist_item_card : R.layout.artist_item_tile, null));
case 4:
return new HeaderViewHolder(DataBindingUtil.inflate(inflater, R.layout.header_item, null, false).getRoot());
default:
return null;
}
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
String image;
switch (getItemViewType(holder.getAdapterPosition())) {
case 0:
TrackListData trackData = tracks.get(getRelPosition(holder.getAdapterPosition()));
image = trackData.trackImage;
((TextView) holder.v.findViewById(R.id.name)).setText(trackData.trackName);
TextView extra = (TextView) holder.v.findViewById(R.id.extra);
if (trackData.artists != null && trackData.artists.size() > 0)
extra.setText(trackData.artists.get(0).artistName);
holder.v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
StaticUtils.play(getRelPosition(holder.getAdapterPosition()), tracks, activity);
ActivityOptionsCompat options = ActivityOptionsCompat.makeCustomAnimation(activity, R.anim.slide_up, R.anim.blank);
activity.startActivity(new Intent(activity, PlayerActivity.class), options.toBundle());
}
});
break;
case 1:
holder.v.findViewById(R.id.menu).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PopupMenu popup = new PopupMenu(v.getContext(), v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.menu_basic, popup.getMenu());
final MenuItem fav = popup.getMenu().findItem(R.id.action_fav);
new Action<Boolean>() {
@NonNull
@Override
public String id() {
return "isAlbumFav";
}
@Nullable
@Override
protected Boolean run() throws InterruptedException {
return pasta.isFavorite(albums.get(getRelPosition(holder.getAdapterPosition())));
}
@Override
protected void done(@Nullable Boolean result) {
if (result == null) return;
if (result) {
fav.setTitle(R.string.unfav);
} else {
fav.setTitle(R.string.fav);
}
}
}.execute();
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(final MenuItem item) {
switch (item.getItemId()) {
case R.id.action_fav:
new Action<Boolean>() {
@NonNull
@Override
public String id() {
return "favAlbum";
}
@Nullable
@Override
protected Boolean run() throws InterruptedException {
if (!pasta.toggleFavorite(albums.get(getRelPosition(holder.getAdapterPosition())))) return null;
else return pasta.isFavorite(albums.get(getRelPosition(holder.getAdapterPosition())));
}
@Override
protected void done(@Nullable Boolean result) {
if (result == null) {
pasta.onError(activity, "favorite album menu action");
return;
}
if (result) {
item.setTitle(R.string.unfav);
} else {
item.setTitle(R.string.fav);
}
}
}.execute();
break;
case R.id.action_web:
activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(StaticUtils.getAlbumUrl(albums.get(getRelPosition(holder.getAdapterPosition())).albumId))));
break;
case R.id.action_share:
AlbumListData data = albums.get(getRelPosition(holder.getAdapterPosition()));
Intent s = new Intent(android.content.Intent.ACTION_SEND);
s.setType("text/plain");
s.putExtra(Intent.EXTRA_SUBJECT, data.albumName);
s.putExtra(Intent.EXTRA_TEXT, StaticUtils.getAlbumUrl(data.albumId));
activity.startActivity(Intent.createChooser(s, data.albumName));
break;
}
return false;
}
});
popup.show();
}
});
AlbumListData albumData = albums.get(getRelPosition(holder.getAdapterPosition()));
image = albumData.albumImage;
if (albumData.artists.size() > 0) {
((TextView) holder.v.findViewById(R.id.artist_name)).setText(albumData.artists.get(0).artistName);
((TextView) holder.v.findViewById(R.id.artist_extra)).setText(albumData.albumDate);
new Action<ArtistListData>() {
@NonNull
@Override
public String id() {
return "gotoArtist";
}
@Nullable
@Override
protected ArtistListData run() throws InterruptedException {
return pasta.getArtist(albums.get(getRelPosition(holder.getAdapterPosition())).artists.get(0).artistId);
}
@Override
protected void done(@Nullable ArtistListData result) {
if (result == null) {
pasta.onError(activity, "artist action");
return;
}
holder.v.findViewById(R.id.artist).setTag(result);
ImageView artistImage = (ImageView) holder.v.findViewById(R.id.artist_image);
if (artistImage != null)
Glide.with(activity).load(result.artistImage).into((ImageView) holder.v.findViewById(R.id.artist_image));
}
}.execute();
holder.v.findViewById(R.id.artist).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ArtistListData artist = (ArtistListData) v.getTag();
if (artist != null) {
Bundle args = new Bundle();
args.putParcelable("artist", artist);
Fragment f = new ArtistFragment();
f.setArguments(args);
activity.getSupportFragmentManager().beginTransaction().replace(R.id.fragment, f).addToBackStack(null).commit();
} else {
new Action<ArtistListData>() {
@NonNull
@Override
public String id() {
return "gotoArtist";
}
@Nullable
@Override
protected ArtistListData run() throws InterruptedException {
return pasta.getArtist(albums.get(getRelPosition(holder.getAdapterPosition())).artists.get(0).artistId);
}
@Override
protected void done(@Nullable ArtistListData result) {
if (result == null) {
pasta.onError(activity, "artist action");
return;
}
Bundle args = new Bundle();
args.putParcelable("artist", result);
Fragment f = new ArtistFragment();
f.setArguments(args);
activity.getSupportFragmentManager().beginTransaction().replace(R.id.fragment, f).addToBackStack(null).commit();
}
}.execute();
}
}
});
} else holder.v.findViewById(R.id.artist).setVisibility(View.GONE);
((TextView) holder.v.findViewById(R.id.name)).setText(albumData.albumName);
((TextView) holder.v.findViewById(R.id.extra)).setText(String.valueOf(albumData.tracks) + " tracks");
holder.v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bundle args = new Bundle();
args.putParcelable("album", albums.get(getRelPosition(holder.getAdapterPosition())));
Fragment f = new AlbumFragment();
f.setArguments(args);
activity.getSupportFragmentManager().beginTransaction().replace(R.id.fragment, f).addToBackStack(null).commit();
}
});
break;
case 2:
holder.v.findViewById(R.id.menu).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PopupMenu popup = new PopupMenu(v.getContext(), v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.menu_playlist, popup.getMenu());
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(final MenuItem item) {
switch (item.getItemId()) {
case R.id.action_fav:
new Action<Boolean>() {
@NonNull
@Override
public String id() {
return "favPlaylist";
}
@Nullable
@Override
protected Boolean run() throws InterruptedException {
if (!pasta.toggleFavorite(playlists.get(getRelPosition(holder.getAdapterPosition())))) {
return null;
} else
return pasta.isFavorite(playlists.get(getRelPosition(holder.getAdapterPosition())));
}
@Override
protected void done(@Nullable Boolean result) {
if (result == null) {
pasta.onError(activity, "favorite playlist menu action");
return;
}
if (result) {
item.setTitle(R.string.unfav);
} else {
item.setTitle(R.string.fav);
}
}
}.execute();
break;
case R.id.action_web:
PlaylistListData data = playlists.get(getRelPosition(holder.getAdapterPosition()));
activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(StaticUtils.getPlaylistUrl(data.playlistOwnerId, data.playlistId))));
break;
case R.id.action_share:
PlaylistListData data2 = playlists.get(getRelPosition(holder.getAdapterPosition()));
Intent s = new Intent(android.content.Intent.ACTION_SEND);
s.setType("text/plain");
s.putExtra(Intent.EXTRA_SUBJECT, data2.playlistName);
s.putExtra(Intent.EXTRA_TEXT, StaticUtils.getPlaylistUrl(data2.playlistOwnerId, data2.playlistId));
activity.startActivity(Intent.createChooser(s, data2.playlistName));
break;
}
return false;
}
});
final MenuItem fav = popup.getMenu().findItem(R.id.action_fav);
fav.setVisible(false);
popup.show();
new Action<Boolean>() {
@NonNull
@Override
public String id() {
return "isPlaylistFav";
}
@Nullable
@Override
protected Boolean run() throws InterruptedException {
return pasta.isFavorite(playlists.get(getRelPosition(holder.getAdapterPosition())));
}
@Override
protected void done(@Nullable Boolean result) {
if (result == null) return;
if (result) {
fav.setTitle(R.string.unfav);
} else {
fav.setTitle(R.string.fav);
}
}
}.execute();
popup.show();
}
});
PlaylistListData playlistData = playlists.get(getRelPosition(holder.getAdapterPosition()));
image = playlistData.playlistImage;
((TextView) holder.v.findViewById(R.id.name)).setText(playlistData.playlistName);
((TextView) holder.v.findViewById(R.id.extra)).setText(playlistData.tracks + " tracks");
holder.v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bundle args = new Bundle();
args.putParcelable("playlist", playlists.get(getRelPosition(holder.getAdapterPosition())));
Fragment f = new PlaylistFragment();
f.setArguments(args);
activity.getSupportFragmentManager().beginTransaction().replace(R.id.fragment, f).addToBackStack(null).commit();
}
});
break;
case 3:
holder.v.findViewById(R.id.menu).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PopupMenu popup = new PopupMenu(v.getContext(), v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.menu_basic, popup.getMenu());
final MenuItem fav = popup.getMenu().findItem(R.id.action_fav);
new Action<Boolean>() {
@NonNull
@Override
public String id() {
return "isArtistFav";
}
@Nullable
@Override
protected Boolean run() throws InterruptedException {
return pasta.isFavorite(artists.get(getRelPosition(holder.getAdapterPosition())));
}
@Override
protected void done(@Nullable Boolean result) {
if (result == null) return;
if (result) {
fav.setTitle(R.string.unfav);
} else {
fav.setTitle(R.string.fav);
}
}
}.execute();
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(final MenuItem item) {
switch (item.getItemId()) {
case R.id.action_fav:
new Action<Boolean>() {
@NonNull
@Override
public String id() {
return "favArtist";
}
@Nullable
@Override
protected Boolean run() throws InterruptedException {
if (!pasta.toggleFavorite(artists.get(getRelPosition(holder.getAdapterPosition())))) {
return null;
} else
return pasta.isFavorite(artists.get(getRelPosition(holder.getAdapterPosition())));
}
@Override
protected void done(@Nullable Boolean result) {
if (result == null) {
pasta.onError(activity, "favorite artist menu action");
return;
}
if (result) {
item.setTitle(R.string.unfav);
} else {
item.setTitle(R.string.fav);
}
}
}.execute();
break;
case R.id.action_web:
activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(StaticUtils.getArtistUrl(artists.get(getRelPosition(holder.getAdapterPosition())).artistId))));
break;
case R.id.action_share:
ArtistListData data = artists.get(getRelPosition(holder.getAdapterPosition()));
Intent s = new Intent(android.content.Intent.ACTION_SEND);
s.setType("text/plain");
s.putExtra(Intent.EXTRA_SUBJECT, data.artistName);
s.putExtra(Intent.EXTRA_TEXT, StaticUtils.getArtistUrl(data.artistId));
activity.startActivity(Intent.createChooser(s, data.artistName));
break;
}
return false;
}
});
popup.show();
}
});
ArtistListData artistData = artists.get(getRelPosition(holder.getAdapterPosition()));
image = artistData.artistImage;
((TextView) holder.v.findViewById(R.id.name)).setText(artistData.artistName);
((TextView) holder.v.findViewById(R.id.extra)).setText(String.valueOf(artistData.followers) + " followers");
holder.v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bundle args = new Bundle();
args.putParcelable("artist", artists.get(getRelPosition(holder.getAdapterPosition())));
Fragment f = new ArtistFragment();
f.setArguments(args);
activity.getSupportFragmentManager().beginTransaction().replace(R.id.fragment, f).addToBackStack(null).commit();
}
});
break;
case 4:
((TextView) holder.v).setText(getSectionName(position));
return;
default:
return;
}
ImageView imageView = (ImageView) holder.v.findViewById(R.id.image);
if (!thumbnails) imageView.setVisibility(View.GONE);
else {
Glide.with(activity).load(image).placeholder(ImageUtils.getVectorDrawable(activity, R.drawable.preload)).into(new GlideDrawableImageViewTarget(imageView) {
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> animation) {
((CustomImageView) getView()).transition(resource);
if (!thumbnails) getView().setVisibility(View.GONE);
View bg = holder.v.findViewById(R.id.bg);
if (!thumbnails || !palette || bg == null) return;
Palette.from(ImageUtils.drawableToBitmap(resource)).generate(new Palette.PaletteAsyncListener() {
@Override
public void onGenerated(Palette palette) {
int defaultColor = dark ? Color.DKGRAY : Color.WHITE;
int color = palette.getLightVibrantColor(defaultColor);
if (dark) color = palette.getDarkVibrantColor(defaultColor);
ValueAnimator animator = ValueAnimator.ofObject(new ArgbEvaluator(), defaultColor, color);
animator.setDuration(250);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int color = (int) animation.getAnimatedValue();
holder.v.findViewById(R.id.bg).setBackgroundColor(color);
View artist = holder.v.findViewById(R.id.artist);
if (artist != null) artist.setBackgroundColor(Color.argb(255, Math.max(Color.red(color) - 10, 0), Math.max(Color.green(color) - 10, 0), Math.max(Color.blue(color) - 10, 0)));
}
});
animator.start();
}
});
}
});
}
}
public String getSectionName(int position) {
if (position == tracks.size() + albums.size() + playlists.size() + 3) return "Artists";
else if (position == tracks.size() + albums.size() + 2) return "Playlists";
else if (position == tracks.size() + 1) return "Albums";
else if (position == 0) return "Tracks";
else return null;
}
public int getAbsPosition(int position) {
if (position > tracks.size() + albums.size() + playlists.size() + 3 && position < tracks.size() + albums.size() + playlists.size() + artists.size() + 4) return position - 4;
else if (position > tracks.size() + albums.size() + 2 && position < tracks.size() + albums.size() + playlists.size() + 3) return position - 3;
else if (position > tracks.size() + 1 && position < tracks.size() + albums.size() + 2) return position - 2;
else if (position > 0 && position < tracks.size() + 1) return position - 1;
else return -1;
}
public int getRelPosition(int position) {
if (position > tracks.size() + albums.size() + playlists.size() + 3 && position < tracks.size() + albums.size() + playlists.size() + artists.size() + 4) return position - (tracks.size() + albums.size() + playlists.size() + 4);
else if (position > tracks.size() + albums.size() + 2 && position < tracks.size() + albums.size() + playlists.size() + 3) return position - (tracks.size() + albums.size() + 3);
else if (position > tracks.size() + 1 && position < tracks.size() + albums.size() + 2) return position - (tracks.size() + 2);
else if (position > 0 && position < tracks.size() + 1) return position - 1;
else return -1;
}
@Override
public int getItemCount() {
if (list == null) return 0;
int sections = 0;
if (tracks.size() > 0) sections++;
if (albums.size() > 0) sections++;
if (playlists.size() > 0) sections++;
if (artists.size() > 0) sections++;
return list.size() + sections;
}
public static class HeaderViewHolder extends ViewHolder {
public View v;
public HeaderViewHolder(View v) {
super(v);
this.v = v;
}
}
public static class TrackViewHolder extends ViewHolder {
public View v;
public TrackViewHolder(View v) {
super(v);
this.v = v;
}
}
public static class AlbumViewHolder extends ViewHolder {
public View v;
public AlbumViewHolder(View v) {
super(v);
this.v = v;
}
}
public static class PlaylistViewHolder extends ViewHolder {
public View v;
public PlaylistViewHolder(View v) {
super(v);
this.v = v;
}
}
public static class ArtistViewHolder extends ViewHolder {
public View v;
public ArtistViewHolder(View v) {
super(v);
this.v = v;
}
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public View v;
public ViewHolder(View v) {
super(v);
this.v = v;
}
}
}