initial work for album and artist lists

This commit is contained in:
dkanada 2020-04-25 13:48:20 +09:00
commit ef0f5e500a
19 changed files with 228 additions and 447 deletions

View file

@ -159,7 +159,7 @@ public class AlbumAdapter extends AbsMultiSelectAdapter<AlbumAdapter.ViewHolder,
@Override
public long getItemId(int position) {
return dataSet.get(position).getId();
return dataSet.get(position).hashCode();
}
@Override

View file

@ -69,7 +69,7 @@ public class ArtistAdapter extends AbsMultiSelectAdapter<ArtistAdapter.ViewHolde
@Override
public long getItemId(int position) {
return dataSet.get(position).getId();
return dataSet.get(position).hashCode();
}
@Override

View file

@ -76,7 +76,7 @@ public class SongAdapter extends AbsMultiSelectAdapter<SongAdapter.ViewHolder, S
@Override
public long getItemId(int position) {
return dataSet.get(position).id;
return dataSet.get(position).hashCode();
}
@Override

View file

@ -0,0 +1,7 @@
package com.kabouzeid.gramophone.interfaces;
import java.util.List;
public interface MediaCallback {
void onLoadMedia(List<?> media);
}

View file

@ -1,83 +0,0 @@
package com.kabouzeid.gramophone.loader;
import android.content.Context;
import android.provider.MediaStore.Audio.AudioColumns;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.kabouzeid.gramophone.model.Album;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.util.PreferenceUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class AlbumLoader {
public static String getSongLoaderSortOrder(Context context) {
return PreferenceUtil.getInstance(context).getAlbumSortOrder() + ", " + PreferenceUtil.getInstance(context).getAlbumSongSortOrder();
}
@NonNull
public static List<Album> getAllAlbums(@NonNull final Context context) {
List<Song> songs = SongLoader.getSongs(SongLoader.makeSongCursor(
context,
null,
null,
getSongLoaderSortOrder(context))
);
return splitIntoAlbums(songs);
}
@NonNull
public static List<Album> getAlbums(@NonNull final Context context, String query) {
List<Song> songs = SongLoader.getSongs(SongLoader.makeSongCursor(
context,
AudioColumns.ALBUM + " LIKE ?",
new String[]{"%" + query + "%"},
getSongLoaderSortOrder(context))
);
return splitIntoAlbums(songs);
}
@NonNull
public static Album getAlbum(@NonNull final Context context, int albumId) {
List<Song> songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, AudioColumns.ALBUM_ID + "=?", new String[]{String.valueOf(albumId)}, getSongLoaderSortOrder(context)));
Album album = new Album(songs);
sortSongsByTrackNumber(album);
return album;
}
@NonNull
public static List<Album> splitIntoAlbums(@Nullable final List<Song> songs) {
List<Album> albums = new ArrayList<>();
if (songs != null) {
for (Song song : songs) {
getOrCreateAlbum(albums, song.albumId).songs.add(song);
}
}
for (Album album : albums) {
sortSongsByTrackNumber(album);
}
return albums;
}
private static Album getOrCreateAlbum(List<Album> albums, int albumId) {
for (Album album : albums) {
if (!album.songs.isEmpty() && album.songs.get(0).albumId == albumId) {
return album;
}
}
Album album = new Album();
albums.add(album);
return album;
}
private static void sortSongsByTrackNumber(Album album) {
Collections.sort(album.songs, (o1, o2) -> o1.trackNumber - o2.trackNumber);
}
}

View file

@ -1,78 +0,0 @@
package com.kabouzeid.gramophone.loader;
import android.content.Context;
import android.provider.MediaStore.Audio.AudioColumns;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.kabouzeid.gramophone.model.Album;
import com.kabouzeid.gramophone.model.Artist;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.util.PreferenceUtil;
import java.util.ArrayList;
import java.util.List;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class ArtistLoader {
public static String getSongLoaderSortOrder(Context context) {
return PreferenceUtil.getInstance(context).getArtistSortOrder() + ", " + PreferenceUtil.getInstance(context).getArtistAlbumSortOrder() + ", " + PreferenceUtil.getInstance(context).getAlbumSongSortOrder();
}
@NonNull
public static List<Artist> getAllArtists(@NonNull final Context context) {
List<Song> songs = SongLoader.getSongs(SongLoader.makeSongCursor(
context,
null,
null,
getSongLoaderSortOrder(context))
);
return splitIntoArtists(AlbumLoader.splitIntoAlbums(songs));
}
@NonNull
public static List<Artist> getArtists(@NonNull final Context context, String query) {
List<Song> songs = SongLoader.getSongs(SongLoader.makeSongCursor(
context,
AudioColumns.ARTIST + " LIKE ?",
new String[]{"%" + query + "%"},
getSongLoaderSortOrder(context))
);
return splitIntoArtists(AlbumLoader.splitIntoAlbums(songs));
}
@NonNull
public static Artist getArtist(@NonNull final Context context, int artistId) {
List<Song> songs = SongLoader.getSongs(SongLoader.makeSongCursor(
context,
AudioColumns.ARTIST_ID + "=?",
new String[]{String.valueOf(artistId)},
getSongLoaderSortOrder(context))
);
return new Artist(AlbumLoader.splitIntoAlbums(songs));
}
@NonNull
public static List<Artist> splitIntoArtists(@Nullable final List<Album> albums) {
List<Artist> artists = new ArrayList<>();
if (albums != null) {
for (Album album : albums) {
getOrCreateArtist(artists, album.getArtistId()).albums.add(album);
}
}
return artists;
}
private static Artist getOrCreateArtist(List<Artist> artists, int artistId) {
for (Artist artist : artists) {
if (!artist.albums.isEmpty() && !artist.albums.get(0).songs.isEmpty() && artist.albums.get(0).songs.get(0).artistId == artistId) {
return artist;
}
}
Artist artist = new Artist();
artists.add(artist);
return artist;
}
}

View file

@ -81,16 +81,16 @@ public class SongLoader {
@NonNull
private static Song getSongFromCursorImpl(@NonNull Cursor cursor) {
final int id = cursor.getInt(0);
final String id = cursor.getString(0);
final String title = cursor.getString(1);
final int trackNumber = cursor.getInt(2);
final int year = cursor.getInt(3);
final long duration = cursor.getLong(4);
final String data = cursor.getString(5);
final long dateModified = cursor.getLong(6);
final int albumId = cursor.getInt(7);
final String albumId = cursor.getString(7);
final String albumName = cursor.getString(8);
final int artistId = cursor.getInt(9);
final String artistId = cursor.getString(9);
final String artistName = cursor.getString(10);
return new Song(id, title, trackNumber, year, duration, data, dateModified, albumId, albumName, artistId, artistName);

View file

@ -4,6 +4,8 @@ import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import org.jellyfin.apiclient.model.dto.BaseItemDto;
import java.util.ArrayList;
import java.util.List;
@ -13,36 +15,48 @@ import java.util.List;
public class Album implements Parcelable {
public final List<Song> songs;
public Album(List<Song> songs) {
this.songs = songs;
public String id;
public String title;
public String artistId;
public String artistName;
public int year;
public Album(BaseItemDto itemDto) {
this.id = itemDto.getId();
this.title = itemDto.getName();
this.artistId = itemDto.getAlbumArtists().get(0).getId();
this.artistName = itemDto.getAlbumArtists().get(0).getName();
if (itemDto.getProductionYear() != null) {
this.year = itemDto.getProductionYear();
}
this.songs = new ArrayList<>();
songs.add(Song.EMPTY_SONG);
}
public Album() {
this.songs = new ArrayList<>();
}
public int getId() {
return safeGetFirstSong().albumId;
public String getId() {
return id;
}
public String getTitle() {
return safeGetFirstSong().albumName;
return title;
}
public int getArtistId() {
return safeGetFirstSong().artistId;
public String getArtistId() {
return artistId;
}
public String getArtistName() {
return safeGetFirstSong().artistName;
return artistName;
}
public int getYear() {
return safeGetFirstSong().year;
}
public long getDateModified() {
return safeGetFirstSong().dateModified;
return year;
}
public int getSongCount() {
@ -59,22 +73,18 @@ public class Album implements Parcelable {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Album that = (Album) o;
return songs != null ? songs.equals(that.songs) : that.songs == null;
Album album = (Album) o;
return id.equals(album.id);
}
@Override
public int hashCode() {
return songs != null ? songs.hashCode() : 0;
return id.hashCode();
}
@Override
public String toString() {
return "Album{" +
"songs=" + songs +
'}';
return id;
}
@Override

View file

@ -6,6 +6,8 @@ import androidx.annotation.NonNull;
import com.kabouzeid.gramophone.util.MusicUtil;
import org.jellyfin.apiclient.model.dto.BaseItemDto;
import java.util.ArrayList;
import java.util.List;
@ -17,16 +19,20 @@ public class Artist implements Parcelable {
public final List<Album> albums;
public Artist(List<Album> albums) {
this.albums = albums;
public String id;
public Artist(BaseItemDto itemDto) {
this.id = itemDto.getId();
this.albums = new ArrayList<>();
}
public Artist() {
this.albums = new ArrayList<>();
}
public int getId() {
return safeGetFirstAlbum().getArtistId();
public String getId() {
return id != null ? id : "";
}
public String getName() {
@ -79,9 +85,7 @@ public class Artist implements Parcelable {
@Override
public String toString() {
return "Artist{" +
"albums=" + albums +
'}';
return id;
}
@Override

View file

@ -9,7 +9,7 @@ public class PlaylistSong extends Song {
public final int idInPlayList;
public PlaylistSong(int id, String title, int trackNumber, int year, long duration, String data, int dateModified, int albumId, String albumName, int artistId, String artistName, final int playlistId, final int idInPlayList) {
super(id, title, trackNumber, year, duration, data, dateModified, albumId, albumName, artistId, artistName);
super("", title, trackNumber, year, duration, data, dateModified, "", albumName, "", artistName);
this.playlistId = playlistId;
this.idInPlayList = idInPlayList;
}

View file

@ -7,21 +7,21 @@ import android.os.Parcelable;
* @author Karim Abou Zeid (kabouzeid)
*/
public class Song implements Parcelable {
public static final Song EMPTY_SONG = new Song(-1, "", -1, -1, -1, "", -1, -1, "", -1, "");
public static final Song EMPTY_SONG = new Song("", "", -1, -1, -1, "", -1, "", "", "", "");
public final int id;
public final String id;
public final String title;
public final int trackNumber;
public final int year;
public final long duration;
public final String data;
public final long dateModified;
public final int albumId;
public final String albumId;
public final String albumName;
public final int artistId;
public final String artistId;
public final String artistName;
public Song(int id, String title, int trackNumber, int year, long duration, String data, long dateModified, int albumId, String albumName, int artistId, String artistName) {
public Song(String id, String title, int trackNumber, int year, long duration, String data, long dateModified, String albumId, String albumName, String artistId, String artistName) {
this.id = id;
this.title = title;
this.trackNumber = trackNumber;
@ -41,53 +41,17 @@ public class Song implements Parcelable {
if (o == null || getClass() != o.getClass()) return false;
Song song = (Song) o;
if (id != song.id) return false;
if (trackNumber != song.trackNumber) return false;
if (year != song.year) return false;
if (duration != song.duration) return false;
if (dateModified != song.dateModified) return false;
if (albumId != song.albumId) return false;
if (artistId != song.artistId) return false;
if (title != null ? !title.equals(song.title) : song.title != null) return false;
if (data != null ? !data.equals(song.data) : song.data != null) return false;
if (albumName != null ? !albumName.equals(song.albumName) : song.albumName != null)
return false;
return artistName != null ? artistName.equals(song.artistName) : song.artistName == null;
return id.equals(song.id);
}
@Override
public int hashCode() {
int result = id;
result = 31 * result + (title != null ? title.hashCode() : 0);
result = 31 * result + trackNumber;
result = 31 * result + year;
result = 31 * result + (int) (duration ^ (duration >>> 32));
result = 31 * result + (data != null ? data.hashCode() : 0);
result = 31 * result + (int) (dateModified ^ (dateModified >>> 32));
result = 31 * result + albumId;
result = 31 * result + (albumName != null ? albumName.hashCode() : 0);
result = 31 * result + artistId;
result = 31 * result + (artistName != null ? artistName.hashCode() : 0);
return result;
return id.hashCode();
}
@Override
public String toString() {
return "Song{" +
"id=" + id +
", title='" + title + '\'' +
", trackNumber=" + trackNumber +
", year=" + year +
", duration=" + duration +
", data='" + data + '\'' +
", dateModified=" + dateModified +
", albumId=" + albumId +
", albumName='" + albumName + '\'' +
", artistId=" + artistId +
", artistName='" + artistName + '\'' +
'}';
return id;
}
@Override
@ -97,30 +61,30 @@ public class Song implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(this.id);
dest.writeString(this.id);
dest.writeString(this.title);
dest.writeInt(this.trackNumber);
dest.writeInt(this.year);
dest.writeLong(this.duration);
dest.writeString(this.data);
dest.writeLong(this.dateModified);
dest.writeInt(this.albumId);
dest.writeString(this.albumId);
dest.writeString(this.albumName);
dest.writeInt(this.artistId);
dest.writeString(this.artistId);
dest.writeString(this.artistName);
}
protected Song(Parcel in) {
this.id = in.readInt();
this.id = in.readString();
this.title = in.readString();
this.trackNumber = in.readInt();
this.year = in.readInt();
this.duration = in.readLong();
this.data = in.readString();
this.dateModified = in.readLong();
this.albumId = in.readInt();
this.albumId = in.readString();
this.albumName = in.readString();
this.artistId = in.readInt();
this.artistId = in.readString();
this.artistName = in.readString();
}

View file

@ -175,7 +175,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
private Handler uiThreadHandler;
private static String getTrackUri(@NonNull Song song) {
return MusicUtil.getSongFileUri(song.id).toString();
return MusicUtil.getSongFileUri(song).toString();
}
@Override
@ -550,7 +550,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
}
public void updateNotification() {
if (playingNotification != null && getCurrentSong().id != -1) {
if (playingNotification != null && getCurrentSong().id != null) {
playingNotification.update();
}
}
@ -567,7 +567,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
private void updateMediaSessionMetaData() {
final Song song = getCurrentSong();
if (song.id == -1) {
if (song.id == null) {
mediaSession.setMetadata(null);
return;
}
@ -990,7 +990,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
break;
case SHUFFLE_MODE_NONE:
this.shuffleMode = shuffleMode;
int currentSongId = getCurrentSong().id;
String currentSongId = getCurrentSong().id;
playingQueue = new ArrayList<>(originalPlayingQueue);
int newPosition = 0;
for (Song song : getPlayingQueue()) {

View file

@ -1,11 +1,8 @@
package com.kabouzeid.gramophone.ui.activities;
import android.content.Context;
import android.graphics.PorterDuff;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.appcompat.widget.Toolbar;
@ -31,26 +28,23 @@ import com.kabouzeid.gramophone.glide.SongGlideRequest;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.interfaces.CabHolder;
import com.kabouzeid.gramophone.interfaces.LoaderIds;
import com.kabouzeid.gramophone.interfaces.MediaCallback;
import com.kabouzeid.gramophone.interfaces.PaletteColorHolder;
import com.kabouzeid.gramophone.loader.AlbumLoader;
import com.kabouzeid.gramophone.misc.SimpleObservableScrollViewCallbacks;
import com.kabouzeid.gramophone.misc.WrappedAsyncTaskLoader;
import com.kabouzeid.gramophone.model.Album;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.ui.activities.base.AbsSlidingMusicPanelActivity;
import com.kabouzeid.gramophone.util.MusicUtil;
import com.kabouzeid.gramophone.util.NavigationUtil;
import com.kabouzeid.gramophone.util.PhonographColorUtil;
import com.kabouzeid.gramophone.util.QueryUtil;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements PaletteColorHolder, CabHolder, LoaderManager.LoaderCallbacks<Album> {
private static final int LOADER_ID = LoaderIds.ALBUM_DETAIL_ACTIVITY;
public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements PaletteColorHolder, CabHolder {
public static final String EXTRA_ALBUM_ID = "extra_album_id";
private Album album;
@ -99,7 +93,12 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
setUpToolBar();
setUpViews();
getSupportLoaderManager().initLoader(LOADER_ID, getIntent().getExtras(), this);
QueryUtil.getAlbum(getIntent().getExtras().getString(EXTRA_ALBUM_ID), new MediaCallback() {
@Override
public void onLoadMedia(List<?> media) {
setAlbum((Album) media.get(0));
}
});
}
@Override
@ -209,10 +208,6 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
});
}
private void reload() {
getSupportLoaderManager().restartLoader(LOADER_ID, getIntent().getExtras(), this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_album_detail, menu);
@ -291,7 +286,6 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
@Override
public void onMediaStoreChanged() {
super.onMediaStoreChanged();
reload();
}
@Override
@ -317,34 +311,4 @@ public class AlbumDetailActivity extends AbsSlidingMusicPanelActivity implements
if (album == null) album = new Album();
return album;
}
@Override
public Loader<Album> onCreateLoader(int id, Bundle args) {
return new AsyncAlbumLoader(this, args.getInt(EXTRA_ALBUM_ID));
}
@Override
public void onLoadFinished(Loader<Album> loader, Album data) {
setAlbum(data);
}
@Override
public void onLoaderReset(Loader<Album> loader) {
this.album = new Album();
adapter.swapDataSet(album.songs);
}
private static class AsyncAlbumLoader extends WrappedAsyncTaskLoader<Album> {
private final int albumId;
public AsyncAlbumLoader(Context context, int albumId) {
super(context);
this.albumId = albumId;
}
@Override
public Album loadInBackground() {
return AlbumLoader.getAlbum(getContext(), albumId);
}
}
}

View file

@ -1,7 +1,5 @@
package com.kabouzeid.gramophone.ui.activities;
import android.content.Context;
import android.content.Intent;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.view.LayoutInflater;
@ -13,8 +11,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
@ -37,22 +33,19 @@ import com.kabouzeid.gramophone.glide.ArtistGlideRequest;
import com.kabouzeid.gramophone.glide.CustomPaletteTarget;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.interfaces.CabHolder;
import com.kabouzeid.gramophone.interfaces.LoaderIds;
import com.kabouzeid.gramophone.interfaces.MediaCallback;
import com.kabouzeid.gramophone.interfaces.PaletteColorHolder;
import com.kabouzeid.gramophone.loader.ArtistLoader;
import com.kabouzeid.gramophone.misc.SimpleObservableScrollViewCallbacks;
import com.kabouzeid.gramophone.misc.WrappedAsyncTaskLoader;
import com.kabouzeid.gramophone.model.Album;
import com.kabouzeid.gramophone.model.Artist;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.ui.activities.base.AbsSlidingMusicPanelActivity;
import com.kabouzeid.gramophone.util.MusicUtil;
import com.kabouzeid.gramophone.util.PhonographColorUtil;
import com.kabouzeid.gramophone.util.PreferenceUtil;
import com.kabouzeid.gramophone.util.QueryUtil;
public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implements PaletteColorHolder, CabHolder, LoaderManager.LoaderCallbacks<Artist> {
private static final int LOADER_ID = LoaderIds.ARTIST_DETAIL_ACTIVITY;
public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implements PaletteColorHolder, CabHolder {
public static final String EXTRA_ARTIST_ID = "extra_artist_id";
@BindView(R.id.list)
@ -119,7 +112,12 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
setUpToolbar();
setUpViews();
getSupportLoaderManager().initLoader(LOADER_ID, getIntent().getExtras(), this);
QueryUtil.getArtist(getIntent().getExtras().getString(EXTRA_ARTIST_ID), new MediaCallback() {
@Override
public void onLoadMedia(List<?> media) {
setArtist((Artist) media.get(0));
}
});
}
@Override
@ -179,10 +177,6 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
this.usePalette = usePalette;
}
private void reload() {
getSupportLoaderManager().restartLoader(LOADER_ID, getIntent().getExtras(), this);
}
private void loadArtistImage() {
ArtistGlideRequest.Builder.from(Glide.with(this), artist)
.generatePalette(this).build()
@ -305,7 +299,6 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
@Override
public void onMediaStoreChanged() {
super.onMediaStoreChanged();
reload();
}
@Override
@ -331,35 +324,4 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
if (artist == null) artist = new Artist();
return artist;
}
@Override
public Loader<Artist> onCreateLoader(int id, Bundle args) {
return new AsyncArtistDataLoader(this, args.getInt(EXTRA_ARTIST_ID));
}
@Override
public void onLoadFinished(Loader<Artist> loader, Artist data) {
setArtist(data);
}
@Override
public void onLoaderReset(Loader<Artist> loader) {
this.artist = new Artist();
songAdapter.swapDataSet(artist.getSongs());
albumAdapter.swapDataSet(artist.albums);
}
private static class AsyncArtistDataLoader extends WrappedAsyncTaskLoader<Artist> {
private final int artistId;
public AsyncArtistDataLoader(Context context, int artistId) {
super(context);
this.artistId = artistId;
}
@Override
public Artist loadInBackground() {
return ArtistLoader.getArtist(getContext(), artistId);
}
}
}

View file

@ -1,34 +1,27 @@
package com.kabouzeid.gramophone.ui.fragments.mainactivity.library.pager;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.GridLayoutManager;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.adapter.album.AlbumAdapter;
import com.kabouzeid.gramophone.interfaces.LoaderIds;
import com.kabouzeid.gramophone.loader.AlbumLoader;
import com.kabouzeid.gramophone.misc.WrappedAsyncTaskLoader;
import com.kabouzeid.gramophone.interfaces.MediaCallback;
import com.kabouzeid.gramophone.model.Album;
import com.kabouzeid.gramophone.util.PreferenceUtil;
import com.kabouzeid.gramophone.util.QueryUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class AlbumsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridLayoutManager> implements LoaderManager.LoaderCallbacks<List<Album>> {
private static final int LOADER_ID = LoaderIds.ALBUMS_FRAGMENT;
public class AlbumsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridLayoutManager> {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().initLoader(LOADER_ID, null, this);
}
@Override
@ -36,18 +29,22 @@ public class AlbumsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFra
return new GridLayoutManager(getActivity(), getGridSize());
}
@NonNull
@Override
protected AlbumAdapter createAdapter() {
int itemLayoutRes = getItemLayoutRes();
notifyLayoutResChanged(itemLayoutRes);
List<Album> dataSet = getAdapter() == null ? new ArrayList<>() : getAdapter().getDataSet();
return new AlbumAdapter(
getLibraryFragment().getMainActivity(),
dataSet,
itemLayoutRes,
loadUsePalette(),
getLibraryFragment());
AlbumAdapter adapter = new AlbumAdapter(getLibraryFragment().getMainActivity(), dataSet, itemLayoutRes, loadUsePalette(), getLibraryFragment());
QueryUtil.getAlbums(new MediaCallback() {
@Override
public void onLoadMedia(List<?> media) {
dataSet.addAll((Collection<Album>) media);
adapter.notifyDataSetChanged();
}
});
return adapter;
}
@Override
@ -67,7 +64,6 @@ public class AlbumsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFra
@Override
protected void setSortOrder(String sortOrder) {
getLoaderManager().restartLoader(LOADER_ID, null, this);
}
@Override
@ -113,32 +109,6 @@ public class AlbumsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFra
@Override
public void onMediaStoreChanged() {
getLoaderManager().restartLoader(LOADER_ID, null, this);
}
@Override
public Loader<List<Album>> onCreateLoader(int id, Bundle args) {
return new AsyncAlbumLoader(getActivity());
}
@Override
public void onLoadFinished(Loader<List<Album>> loader, List<Album> data) {
getAdapter().swapDataSet(data);
}
@Override
public void onLoaderReset(Loader<List<Album>> loader) {
getAdapter().swapDataSet(new ArrayList<>());
}
private static class AsyncAlbumLoader extends WrappedAsyncTaskLoader<List<Album>> {
public AsyncAlbumLoader(Context context) {
super(context);
}
@Override
public List<Album> loadInBackground() {
return AlbumLoader.getAllAlbums(getContext());
}
super.onMediaStoreChanged();
}
}

View file

@ -1,34 +1,28 @@
package com.kabouzeid.gramophone.ui.fragments.mainactivity.library.pager;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.GridLayoutManager;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.adapter.artist.ArtistAdapter;
import com.kabouzeid.gramophone.interfaces.LoaderIds;
import com.kabouzeid.gramophone.loader.ArtistLoader;
import com.kabouzeid.gramophone.misc.WrappedAsyncTaskLoader;
import com.kabouzeid.gramophone.interfaces.MediaCallback;
import com.kabouzeid.gramophone.model.Artist;
import com.kabouzeid.gramophone.util.PreferenceUtil;
import com.kabouzeid.gramophone.util.QueryUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class ArtistsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFragment<ArtistAdapter, GridLayoutManager> implements LoaderManager.LoaderCallbacks<List<Artist>> {
private static final int LOADER_ID = LoaderIds.ARTISTS_FRAGMENT;
public class ArtistsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFragment<ArtistAdapter, GridLayoutManager> {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().initLoader(LOADER_ID, null, this);
}
@NonNull
@ -43,22 +37,28 @@ public class ArtistsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFr
int itemLayoutRes = getItemLayoutRes();
notifyLayoutResChanged(itemLayoutRes);
List<Artist> dataSet = getAdapter() == null ? new ArrayList<>() : getAdapter().getDataSet();
return new ArtistAdapter(
getLibraryFragment().getMainActivity(),
dataSet,
itemLayoutRes,
loadUsePalette(),
getLibraryFragment());
ArtistAdapter adapter = new ArtistAdapter(getLibraryFragment().getMainActivity(), dataSet, itemLayoutRes, loadUsePalette(), getLibraryFragment());
QueryUtil.getArtists(new MediaCallback() {
@Override
public void onLoadMedia(List<?> media) {
dataSet.addAll((Collection<Artist>) media);
adapter.notifyDataSetChanged();
}
});
return adapter;
}
@Override
protected int getEmptyMessage() {
return R.string.no_artists;
}
@Override
public void onMediaStoreChanged() {
getLoaderManager().restartLoader(LOADER_ID, null, this);
super.onMediaStoreChanged();
}
@Override
@ -73,7 +73,6 @@ public class ArtistsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFr
@Override
protected void setSortOrder(String sortOrder) {
getLoaderManager().restartLoader(LOADER_ID, null, this);
}
@Override
@ -116,33 +115,4 @@ public class ArtistsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFr
getLayoutManager().setSpanCount(gridSize);
getAdapter().notifyDataSetChanged();
}
@Override
public Loader<List<Artist>> onCreateLoader(int id, Bundle args) {
return new AsyncArtistLoader(getActivity());
}
@Override
public void onLoadFinished(Loader<List<Artist>> loader, List<Artist> data) {
getAdapter().swapDataSet(data);
}
@Override
public void onLoaderReset(Loader<List<Artist>> loader) {
getAdapter().swapDataSet(new ArrayList<>());
}
private static class AsyncArtistLoader extends WrappedAsyncTaskLoader<List<Artist>> {
public AsyncArtistLoader(Context context) {
super(context);
}
@Override
public List<Artist> loadInBackground() {
return ArtistLoader.getAllArtists(getContext());
}
}
}

View file

@ -37,8 +37,8 @@ import java.util.Locale;
* @author Karim Abou Zeid (kabouzeid)
*/
public class MusicUtil {
public static Uri getSongFileUri(int songId) {
return ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, songId);
public static Uri getSongFileUri(Song song) {
return Uri.parse(song.data);
}
@NonNull

View file

@ -1,17 +1,12 @@
package com.kabouzeid.gramophone.util;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.media.audiofx.AudioEffect;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityOptionsCompat;
import androidx.core.util.Pair;
import android.widget.Toast;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.model.Genre;
import com.kabouzeid.gramophone.model.Playlist;
import com.kabouzeid.gramophone.ui.activities.AlbumDetailActivity;
@ -24,7 +19,7 @@ import com.kabouzeid.gramophone.ui.activities.PlaylistDetailActivity;
*/
public class NavigationUtil {
public static void goToArtist(@NonNull final Activity activity, final int artistId, @Nullable Pair... sharedElements) {
public static void goToArtist(@NonNull final Activity activity, final String artistId, @Nullable Pair... sharedElements) {
final Intent intent = new Intent(activity, ArtistDetailActivity.class);
intent.putExtra(ArtistDetailActivity.EXTRA_ARTIST_ID, artistId);
@ -36,7 +31,7 @@ public class NavigationUtil {
}
}
public static void goToAlbum(@NonNull final Activity activity, final int albumId, @Nullable Pair... sharedElements) {
public static void goToAlbum(@NonNull final Activity activity, final String albumId, @Nullable Pair... sharedElements) {
final Intent intent = new Intent(activity, AlbumDetailActivity.class);
intent.putExtra(AlbumDetailActivity.EXTRA_ALBUM_ID, albumId);

View file

@ -0,0 +1,96 @@
package com.kabouzeid.gramophone.util;
import com.kabouzeid.gramophone.App;
import com.kabouzeid.gramophone.interfaces.MediaCallback;
import com.kabouzeid.gramophone.model.Album;
import com.kabouzeid.gramophone.model.Artist;
import org.jellyfin.apiclient.interaction.Response;
import org.jellyfin.apiclient.model.dto.BaseItemDto;
import org.jellyfin.apiclient.model.querying.ItemQuery;
import org.jellyfin.apiclient.model.querying.ItemsResult;
import java.util.ArrayList;
import java.util.List;
public class QueryUtil {
public static void getAlbums(MediaCallback callback) {
ItemQuery query = new ItemQuery();
query.setIncludeItemTypes(new String[]{"MusicAlbum"});
query.setUserId(App.getApiClient().getCurrentUserId());
query.setLimit(10);
query.setRecursive(true);
App.getApiClient().GetItemsAsync(query, new Response<ItemsResult>() {
@Override
public void onResponse(ItemsResult result) {
List<Album> albums = new ArrayList<>();
for (BaseItemDto itemDto : result.getItems()) {
albums.add(new Album(itemDto));
}
callback.onLoadMedia(albums);
}
@Override
public void onError(Exception exception) {
exception.printStackTrace();
}
});
}
public static void getAlbum(String id, MediaCallback callback) {
App.getApiClient().GetItemAsync(id, App.getApiClient().getCurrentUserId(), new Response<BaseItemDto>() {
@Override
public void onResponse(BaseItemDto itemDto) {
List<Album> albums = new ArrayList<>();
albums.add(new Album(itemDto));
callback.onLoadMedia(albums);
}
@Override
public void onError(Exception exception) {
exception.printStackTrace();
}
});
}
public static void getArtists(MediaCallback callback) {
ItemQuery query = new ItemQuery();
query.setIncludeItemTypes(new String[]{"MusicArtist"});
query.setUserId(App.getApiClient().getCurrentUserId());
query.setLimit(10);
query.setRecursive(true);
App.getApiClient().GetItemsAsync(query, new Response<ItemsResult>() {
@Override
public void onResponse(ItemsResult result) {
List<Artist> artists = new ArrayList<>();
for (BaseItemDto itemDto : result.getItems()) {
artists.add(new Artist(itemDto));
}
callback.onLoadMedia(artists);
}
@Override
public void onError(Exception exception) {
exception.printStackTrace();
}
});
}
public static void getArtist(String id, MediaCallback callback) {
App.getApiClient().GetItemAsync(id, App.getApiClient().getCurrentUserId(), new Response<BaseItemDto>() {
@Override
public void onResponse(BaseItemDto itemDto) {
List<Artist> artists = new ArrayList<>();
artists.add(new Artist(itemDto));
callback.onLoadMedia(artists);
}
@Override
public void onError(Exception exception) {
exception.printStackTrace();
}
});
}
}