diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 61a9130c..fb7f4a8a 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index d5d35ec4..860da66a 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + diff --git a/app/src/main/java/com/cappielloantonio/play/database/AppDatabase.java b/app/src/main/java/com/cappielloantonio/play/database/AppDatabase.java index c1ac67b5..e8f1fb7b 100644 --- a/app/src/main/java/com/cappielloantonio/play/database/AppDatabase.java +++ b/app/src/main/java/com/cappielloantonio/play/database/AppDatabase.java @@ -29,7 +29,7 @@ import com.cappielloantonio.play.model.Song; import com.cappielloantonio.play.model.SongArtistCross; import com.cappielloantonio.play.model.SongGenreCross; -@Database(entities = {Album.class, Artist.class, Genre.class, Playlist.class, Song.class, RecentSearch.class, SongGenreCross.class, Queue.class, AlbumArtistCross.class, SongArtistCross.class, PlaylistSongCross.class}, version = 13, exportSchema = false) +@Database(entities = {Album.class, Artist.class, Genre.class, Playlist.class, Song.class, RecentSearch.class, SongGenreCross.class, Queue.class, AlbumArtistCross.class, SongArtistCross.class, PlaylistSongCross.class}, version = 14, exportSchema = false) public abstract class AppDatabase extends RoomDatabase { private static final String TAG = "AppDatabase"; private final static String DB_NAME = "play_db"; diff --git a/app/src/main/java/com/cappielloantonio/play/database/dao/SongDao.java b/app/src/main/java/com/cappielloantonio/play/database/dao/SongDao.java index 75b81199..beca3398 100644 --- a/app/src/main/java/com/cappielloantonio/play/database/dao/SongDao.java +++ b/app/src/main/java/com/cappielloantonio/play/database/dao/SongDao.java @@ -48,9 +48,12 @@ public interface SongDao { @Query("SELECT * FROM song WHERE albumId = :albumID ORDER BY trackNumber ASC") LiveData> getLiveAlbumSong(String albumID); - @Query("SELECT song.* FROM song INNER JOIN playlist_song_cross ON song.id = playlist_song_cross.song_id AND playlist_song_cross.playlist_id = :playlistID") + @Query("SELECT song.* FROM song INNER JOIN playlist_song_cross ON song.id = playlist_song_cross.song_id AND playlist_song_cross.playlist_id = :playlistID ORDER BY playlist_song_cross.item_number") LiveData> getLivePlaylistSong(String playlistID); + @Query("SELECT song.* FROM song INNER JOIN playlist_song_cross ON song.id = playlist_song_cross.song_id AND playlist_song_cross.playlist_id = :playlistID ORDER BY playlist_song_cross.item_number") + List getPlaylistSong(String playlistID); + @Query("SELECT * FROM song WHERE albumId = :albumID ORDER BY trackNumber ASC") List getAlbumSong(String albumID); diff --git a/app/src/main/java/com/cappielloantonio/play/model/PlaylistSongCross.java b/app/src/main/java/com/cappielloantonio/play/model/PlaylistSongCross.java index 797efae9..d45076f5 100644 --- a/app/src/main/java/com/cappielloantonio/play/model/PlaylistSongCross.java +++ b/app/src/main/java/com/cappielloantonio/play/model/PlaylistSongCross.java @@ -15,9 +15,13 @@ public class PlaylistSongCross { @ColumnInfo(name = "song_id") private String songId; - public PlaylistSongCross(String playlistId, String songId) { + @ColumnInfo(name = "item_number") + private int itemNumber; + + public PlaylistSongCross(String playlistId, String songId, int itemNumber) { this.playlistId = playlistId; this.songId = songId; + this.itemNumber = itemNumber; } public String getPlaylistId() { @@ -35,4 +39,8 @@ public class PlaylistSongCross { public void setSongId(String songId) { this.songId = songId; } + + public int getItemNumber() { return itemNumber; } + + public void setItemNumber(int itemNumber) { this.itemNumber = itemNumber; } } diff --git a/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java b/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java index 3462df29..0f81c2a5 100644 --- a/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java +++ b/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java @@ -293,6 +293,23 @@ public class SongRepository { return sample; } + public List getPlaylistSong(String playlistID) { + List songs = new ArrayList<>(); + + GetSongsByPlaylistIDThreadSafe playlistThread = new GetSongsByPlaylistIDThreadSafe(songDao, playlistID); + Thread thread = new Thread(playlistThread); + thread.start(); + + try { + thread.join(); + songs = playlistThread.getSongs(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + return songs; + } + private static class GetRandomSongsByArtistIDThreadSafe implements Runnable { private SongDao songDao; private String artistID; @@ -509,4 +526,24 @@ public class SongRepository { return sample; } } + + private static class GetSongsByPlaylistIDThreadSafe implements Runnable { + private SongDao songDao; + private String playlistID; + private List songs = new ArrayList<>(); + + public GetSongsByPlaylistIDThreadSafe(SongDao songDao, String playlistID) { + this.songDao = songDao; + this.playlistID = playlistID; + } + + @Override + public void run() { + songs = songDao.getPlaylistSong(playlistID); + } + + public List getSongs() { + return songs; + } + } } diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistPageFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistPageFragment.java index f709287b..8f4d5d72 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistPageFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlaylistPageFragment.java @@ -3,9 +3,13 @@ package com.cappielloantonio.play.ui.fragment; import android.graphics.PorterDuff; import android.os.Bundle; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; import androidx.fragment.app.Fragment; @@ -20,6 +24,7 @@ import com.cappielloantonio.play.glide.CustomGlideRequest; import com.cappielloantonio.play.repository.QueueRepository; import com.cappielloantonio.play.service.MusicPlayerRemote; import com.cappielloantonio.play.ui.activity.MainActivity; +import com.cappielloantonio.play.util.DownloadUtil; import com.cappielloantonio.play.util.PreferenceUtil; import com.cappielloantonio.play.viewmodel.PlaylistPageViewModel; @@ -33,6 +38,18 @@ public class PlaylistPageFragment extends Fragment { private SongResultSearchAdapter songResultSearchAdapter; + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.playlist_page_menu, menu); + } + @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); @@ -68,6 +85,19 @@ public class PlaylistPageFragment extends Fragment { bind = null; } + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.action_download_playlist: + DownloadUtil.getDownloadTracker(requireContext()).toggleDownload(playlistPageViewModel.getPlaylistSongList()); + return true; + default: + break; + } + + return false; + } + private void init() { playlistPageViewModel.setPlaylist(getArguments().getParcelable("playlist_object")); } @@ -91,7 +121,7 @@ public class PlaylistPageFragment extends Fragment { } private void initMusicButton() { - playlistPageViewModel.getPlaylistSongList().observe(requireActivity(), songs -> { + playlistPageViewModel.getPlaylistSongLiveList().observe(requireActivity(), songs -> { if(bind != null) { bind.playlistPagePlayButton.setOnClickListener(v -> { QueueRepository queueRepository = new QueueRepository(App.getInstance()); @@ -131,7 +161,7 @@ public class PlaylistPageFragment extends Fragment { songResultSearchAdapter = new SongResultSearchAdapter(activity, requireContext(), getChildFragmentManager()); bind.playlistRecyclerView.setAdapter(songResultSearchAdapter); - playlistPageViewModel.getPlaylistSongList().observe(requireActivity(), songs -> { + playlistPageViewModel.getPlaylistSongLiveList().observe(requireActivity(), songs -> { songResultSearchAdapter.setItems(songs); }); } diff --git a/app/src/main/java/com/cappielloantonio/play/util/SyncUtil.java b/app/src/main/java/com/cappielloantonio/play/util/SyncUtil.java index 458aa0a9..888e69bc 100644 --- a/app/src/main/java/com/cappielloantonio/play/util/SyncUtil.java +++ b/app/src/main/java/com/cappielloantonio/play/util/SyncUtil.java @@ -2,6 +2,7 @@ package com.cappielloantonio.play.util; import android.content.Context; import android.os.Bundle; +import android.util.Log; import com.cappielloantonio.play.App; import com.cappielloantonio.play.interfaces.MediaCallback; @@ -226,10 +227,11 @@ public class SyncUtil { App.getApiClientInstance(context).GetPlaylistItems(query, new Response() { @Override public void onResponse(ItemsResult result) { + int itemNumber = 0; ArrayList crosses = new ArrayList<>(); for (BaseItemDto itemDto : result.getItems()) { - crosses.add(new PlaylistSongCross(playlistId, itemDto.getId())); + crosses.add(new PlaylistSongCross(playlistId, itemDto.getId(), itemNumber++)); } callback.onLoadMedia(crosses); diff --git a/app/src/main/java/com/cappielloantonio/play/viewmodel/PlaylistPageViewModel.java b/app/src/main/java/com/cappielloantonio/play/viewmodel/PlaylistPageViewModel.java index 37a8ebbb..40817324 100644 --- a/app/src/main/java/com/cappielloantonio/play/viewmodel/PlaylistPageViewModel.java +++ b/app/src/main/java/com/cappielloantonio/play/viewmodel/PlaylistPageViewModel.java @@ -17,7 +17,7 @@ public class PlaylistPageViewModel extends AndroidViewModel { private SongRepository songRepository; - private LiveData> songList; + private LiveData> songLiveList; private Playlist playlist; @@ -27,9 +27,13 @@ public class PlaylistPageViewModel extends AndroidViewModel { songRepository = new SongRepository(application); } - public LiveData> getPlaylistSongList() { - songList = songRepository.getPlaylistLiveSong(playlist.getId()); - return songList; + public LiveData> getPlaylistSongLiveList() { + songLiveList = songRepository.getPlaylistLiveSong(playlist.getId()); + return songLiveList; + } + + public List getPlaylistSongList() { + return songRepository.getPlaylistSong(playlist.getId()); } public Playlist getPlaylist() { diff --git a/app/src/main/res/menu/playlist_page_menu.xml b/app/src/main/res/menu/playlist_page_menu.xml new file mode 100644 index 00000000..5f987865 --- /dev/null +++ b/app/src/main/res/menu/playlist_page_menu.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file