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 30de9441..3c96697b 100644 --- a/app/src/main/java/com/cappielloantonio/play/database/AppDatabase.java +++ b/app/src/main/java/com/cappielloantonio/play/database/AppDatabase.java @@ -23,7 +23,7 @@ import com.cappielloantonio.play.model.RecentSearch; import com.cappielloantonio.play.model.Song; import com.cappielloantonio.play.model.SongGenreCross; -@Database(entities = {Album.class, Artist.class, Genre.class, Playlist.class, Song.class, RecentSearch.class, SongGenreCross.class, Queue.class}, version = 7, exportSchema = false) +@Database(entities = {Album.class, Artist.class, Genre.class, Playlist.class, Song.class, RecentSearch.class, SongGenreCross.class, Queue.class}, version = 8, exportSchema = false) public abstract class AppDatabase extends RoomDatabase { private static final String TAG = "AppDatabase"; 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 294c66d5..de22be06 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 @@ -43,7 +43,10 @@ public interface SongDao { LiveData> getArtistTopSongs(String artistID); @Query("SELECT * FROM song WHERE albumId = :albumID ORDER BY trackNumber ASC") - LiveData> getAlbumSong(String albumID); + LiveData> getLiveAlbumSong(String albumID); + + @Query("SELECT * FROM song WHERE albumId = :albumID ORDER BY trackNumber ASC") + List getAlbumSong(String albumID); @Query("SELECT * FROM song INNER Join song_genre_cross ON song.id = song_genre_cross.song_id AND song_genre_cross.genre_id = :genreID") LiveData> getSongByGenre(String genreID); diff --git a/app/src/main/java/com/cappielloantonio/play/helper/MusicPlayerRemote.java b/app/src/main/java/com/cappielloantonio/play/helper/MusicPlayerRemote.java index d3742afe..e251629b 100644 --- a/app/src/main/java/com/cappielloantonio/play/helper/MusicPlayerRemote.java +++ b/app/src/main/java/com/cappielloantonio/play/helper/MusicPlayerRemote.java @@ -13,8 +13,10 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.cappielloantonio.play.App; import com.cappielloantonio.play.R; import com.cappielloantonio.play.model.Song; +import com.cappielloantonio.play.repository.QueueRepository; import com.cappielloantonio.play.service.MusicService; import java.util.ArrayList; @@ -226,15 +228,17 @@ public class MusicPlayerRemote { public static boolean playNext(Song song) { if (musicService != null) { + QueueRepository queueRepository = new QueueRepository(App.getInstance()); + if (getPlayingQueue().size() > 0) { musicService.addSong(getPosition() + 1, song); + queueRepository.insertAllAndStartNew(getPlayingQueue()); } else { - List queue = new ArrayList<>(); - queue.add(song); - openQueue(queue, 0, false); + List songToEnqueue = new ArrayList<>(); + songToEnqueue.add(song); + queueRepository.insertAllAndStartNew(songToEnqueue); + openQueue(songToEnqueue, 0, true); } - - Toast.makeText(musicService, musicService.getResources().getString(R.string.added_title_to_queue), Toast.LENGTH_SHORT).show(); return true; } @@ -243,14 +247,18 @@ public class MusicPlayerRemote { public static boolean playNext(@NonNull List songs) { if (musicService != null) { + QueueRepository queueRepository = new QueueRepository(App.getInstance()); + if (getPlayingQueue().size() > 0) { musicService.addSongs(getPosition() + 1, songs); + queueRepository.insertAllAndStartNew(getPlayingQueue()); } else { - openQueue(songs, 0, false); + List songToEnqueue = new ArrayList<>(); + songToEnqueue.addAll(songs); + queueRepository.insertAllAndStartNew(songToEnqueue); + openQueue(songToEnqueue, 0, true); } - final String toast = songs.size() == 1 ? musicService.getResources().getString(R.string.added_title_to_queue) : musicService.getResources().getString(R.string.added_x_titles_to_queue, songs.size()); - Toast.makeText(musicService, toast, Toast.LENGTH_SHORT).show(); return true; } @@ -259,15 +267,17 @@ public class MusicPlayerRemote { public static boolean enqueue(Song song) { if (musicService != null) { + QueueRepository queueRepository = new QueueRepository(App.getInstance()); + if (getPlayingQueue().size() > 0) { musicService.addSong(song); + queueRepository.insertAllAndStartNew(getPlayingQueue()); } else { - List queue = new ArrayList<>(); - queue.add(song); - openQueue(queue, 0, false); + List songToEnqueue = new ArrayList<>(); + songToEnqueue.add(song); + queueRepository.insertAllAndStartNew(songToEnqueue); + openQueue(songToEnqueue, 0, true); } - - Toast.makeText(musicService, musicService.getResources().getString(R.string.added_title_to_queue), Toast.LENGTH_SHORT).show(); return true; } @@ -276,14 +286,18 @@ public class MusicPlayerRemote { public static boolean enqueue(@NonNull List songs) { if (musicService != null) { + QueueRepository queueRepository = new QueueRepository(App.getInstance()); + if (getPlayingQueue().size() > 0) { musicService.addSongs(songs); + queueRepository.insertAllAndStartNew(getPlayingQueue()); } else { - openQueue(songs, 0, false); + List songToEnqueue = new ArrayList<>(); + songToEnqueue.addAll(songs); + queueRepository.insertAllAndStartNew(songToEnqueue); + openQueue(songToEnqueue, 0, true); } - final String toast = songs.size() == 1 ? musicService.getResources().getString(R.string.added_title_to_queue) : musicService.getResources().getString(R.string.added_x_titles_to_queue, songs.size()); - Toast.makeText(musicService, toast, Toast.LENGTH_SHORT).show(); return true; } diff --git a/app/src/main/java/com/cappielloantonio/play/model/Queue.java b/app/src/main/java/com/cappielloantonio/play/model/Queue.java index efd9dbe3..84e4a158 100644 --- a/app/src/main/java/com/cappielloantonio/play/model/Queue.java +++ b/app/src/main/java/com/cappielloantonio/play/model/Queue.java @@ -9,22 +9,14 @@ import androidx.room.PrimaryKey; public class Queue { @NonNull @PrimaryKey - @ColumnInfo(name = "id") - private String songID; - @ColumnInfo(name = "track_order") private int trackOrder; - public Queue(String songID, int trackOrder) { - this.songID = songID; + @ColumnInfo(name = "id") + private String songID; + + public Queue(int trackOrder, String songID) { this.trackOrder = trackOrder; - } - - public String getSongID() { - return songID; - } - - public void setSongID(String songID) { this.songID = songID; } @@ -35,4 +27,12 @@ public class Queue { public void setTrackOrder(int trackOrder) { this.trackOrder = trackOrder; } + + public String getSongID() { + return songID; + } + + public void setSongID(String songID) { + this.songID = songID; + } } diff --git a/app/src/main/java/com/cappielloantonio/play/repository/QueueRepository.java b/app/src/main/java/com/cappielloantonio/play/repository/QueueRepository.java index 2d027e29..f7cdcf69 100644 --- a/app/src/main/java/com/cappielloantonio/play/repository/QueueRepository.java +++ b/app/src/main/java/com/cappielloantonio/play/repository/QueueRepository.java @@ -47,8 +47,8 @@ public class QueueRepository { return songs; } - public void insert(Song song) { - InsertThreadSafe insert = new InsertThreadSafe(queueDao, song); + public void insert(Song song, int position) { + InsertThreadSafe insert = new InsertThreadSafe(queueDao, song, position); Thread thread = new Thread(insert); thread.start(); } @@ -111,15 +111,17 @@ public class QueueRepository { private static class InsertThreadSafe implements Runnable { private QueueDao queueDao; private Song song; + private int position; - public InsertThreadSafe(QueueDao queueDao, Song song) { + public InsertThreadSafe(QueueDao queueDao, Song song, int position) { this.queueDao = queueDao; this.song = song; + this.position = position; } @Override public void run() { - queueDao.insert(QueueUtil.getQueueElementFromSong(song)); + queueDao.insert(QueueUtil.getQueueElementFromSong(song, position)); } } 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 867b363e..7e1c8fbc 100644 --- a/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java +++ b/app/src/main/java/com/cappielloantonio/play/repository/SongRepository.java @@ -12,6 +12,7 @@ import com.cappielloantonio.play.model.Song; import com.cappielloantonio.play.model.SongGenreCross; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class SongRepository { @@ -80,10 +81,31 @@ public class SongRepository { } public LiveData> getAlbumListLiveSong(String albumID) { - listLiveAlbumSongs = songDao.getAlbumSong(albumID); + listLiveAlbumSongs = songDao.getLiveAlbumSong(albumID); return listLiveAlbumSongs; } + public List getAlbumListSong(String albumID, boolean randomOrder) { + List songs = new ArrayList<>(); + + GetSongsByAlbumIDThreadSafe suggestionsThread = new GetSongsByAlbumIDThreadSafe(songDao, albumID); + Thread thread = new Thread(suggestionsThread); + thread.start(); + + try { + thread.join(); + songs = suggestionsThread.getSongs(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + if(randomOrder) { + Collections.shuffle(songs); + } + + return songs; + } + public LiveData> getFilteredListLiveSong(ArrayList filters) { listLiveFilteredSongs = songDao.getFilteredSong(filters); return listLiveFilteredSongs; @@ -268,6 +290,26 @@ public class SongRepository { return song; } + private static class GetSongsByAlbumIDThreadSafe implements Runnable { + private SongDao songDao; + private String albumID; + private List songs = new ArrayList<>(); + + public GetSongsByAlbumIDThreadSafe(SongDao songDao, String albumID) { + this.songDao = songDao; + this.albumID = albumID; + } + + @Override + public void run() { + songs = songDao.getAlbumSong(albumID); + } + + public List getSongs() { + return songs; + } + } + private static class ExistThreadSafe implements Runnable { private SongDao songDao; private Song song; diff --git a/app/src/main/java/com/cappielloantonio/play/ui/activities/MainActivity.java b/app/src/main/java/com/cappielloantonio/play/ui/activities/MainActivity.java index 824d8ace..c05377e3 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/activities/MainActivity.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/activities/MainActivity.java @@ -3,6 +3,7 @@ package com.cappielloantonio.play.ui.activities; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.os.Bundle; +import android.util.Log; import android.view.View; import androidx.annotation.NonNull; @@ -169,7 +170,8 @@ public class MainActivity extends BaseActivity { @Override public void onStateChanged(@NonNull View view, int state) { switch (state) { - case BottomSheetBehavior.STATE_SETTLING: + case BottomSheetBehavior.STATE_SETTLING | BottomSheetBehavior.STATE_COLLAPSED: + Log.i(TAG, "onStateChanged: IS_SETTLING | IS_COLLAPSING"); PlayerBottomSheetFragment playerBottomSheetFragment = (PlayerBottomSheetFragment) getSupportFragmentManager().findFragmentByTag("PlayerBottomSheet"); if (playerBottomSheetFragment == null) break; @@ -179,17 +181,22 @@ public class MainActivity extends BaseActivity { MusicPlayerRemote.quitPlaying(); mainViewModel.deleteQueue(); break; + } } @Override public void onSlide(@NonNull View view, float slideOffset) { PlayerBottomSheetFragment playerBottomSheetFragment = (PlayerBottomSheetFragment) getSupportFragmentManager().findFragmentByTag("PlayerBottomSheet"); - if (playerBottomSheetFragment == null) return; + if (playerBottomSheetFragment == null) { + return; + } + else { - float condensedSlideOffset = Math.max(0.0f, Math.min(0.2f, slideOffset - 0.2f)) / 0.2f; - playerBottomSheetFragment.getPlayerHeader().setAlpha(1 - condensedSlideOffset); - playerBottomSheetFragment.getPlayerHeader().setVisibility(condensedSlideOffset > 0.99 ? View.GONE : View.VISIBLE); + float condensedSlideOffset = Math.max(0.0f, Math.min(0.2f, slideOffset - 0.2f)) / 0.2f; + playerBottomSheetFragment.getPlayerHeader().setAlpha(1 - condensedSlideOffset); + playerBottomSheetFragment.getPlayerHeader().setVisibility(condensedSlideOffset > 0.99 ? View.GONE : View.VISIBLE); + } } }; diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerBottomSheetFragment.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerBottomSheetFragment.java index b3f40eeb..4df51467 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerBottomSheetFragment.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/PlayerBottomSheetFragment.java @@ -182,7 +182,7 @@ public class PlayerBottomSheetFragment extends Fragment implements MusicServiceE */ playerBottomSheetViewModel.orderSongAfterSwap(playerSongQueueAdapter.getItems()); MusicPlayerRemote.moveSong(originalPosition, toPosition); - bind.playerBodyLayout.playerSongCoverViewPager.setCurrentItem(MusicPlayerRemote.getPosition(), true); + bind.playerBodyLayout.playerSongCoverViewPager.setCurrentItem(MusicPlayerRemote.getPosition(), false); originalPosition = -1; fromPosition = -1; @@ -195,7 +195,7 @@ public class PlayerBottomSheetFragment extends Fragment implements MusicServiceE MusicPlayerRemote.removeFromQueue(viewHolder.getBindingAdapterPosition()); playerBottomSheetViewModel.removeSong(viewHolder.getBindingAdapterPosition()); bind.playerBodyLayout.playerQueueRecyclerView.getAdapter().notifyItemRemoved(viewHolder.getBindingAdapterPosition()); - bind.playerBodyLayout.playerSongCoverViewPager.setCurrentItem(MusicPlayerRemote.getPosition(), true); + bind.playerBodyLayout.playerSongCoverViewPager.setCurrentItem(MusicPlayerRemote.getPosition(), false); } else { bind.playerBodyLayout.playerQueueRecyclerView.getAdapter().notifyDataSetChanged(); @@ -296,10 +296,6 @@ public class PlayerBottomSheetFragment extends Fragment implements MusicServiceE setSongInfo(song); } - private void setCurrentItemInSlideView(boolean smoothScroll) { - - } - @Override public void onServiceConnected() { setSongInfo(MusicPlayerRemote.getCurrentSong()); diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/AlbumBottomSheetDialog.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/AlbumBottomSheetDialog.java index cf690345..edd56a63 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/AlbumBottomSheetDialog.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/AlbumBottomSheetDialog.java @@ -12,17 +12,26 @@ import androidx.annotation.Nullable; import androidx.lifecycle.ViewModelProvider; import androidx.navigation.fragment.NavHostFragment; +import com.cappielloantonio.play.App; import com.cappielloantonio.play.R; import com.cappielloantonio.play.glide.CustomGlideRequest; +import com.cappielloantonio.play.helper.MusicPlayerRemote; import com.cappielloantonio.play.model.Album; import com.cappielloantonio.play.model.Artist; +import com.cappielloantonio.play.model.Song; +import com.cappielloantonio.play.repository.QueueRepository; +import com.cappielloantonio.play.repository.SongRepository; +import com.cappielloantonio.play.ui.activities.MainActivity; import com.cappielloantonio.play.viewmodel.AlbumBottomSheetViewModel; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import java.util.List; + public class AlbumBottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener { private static final String TAG = "AlbumBottomSheetDialog"; private AlbumBottomSheetViewModel albumBottomSheetViewModel; + private SongRepository songRepository; private Album album; private ImageView coverAlbum; @@ -47,6 +56,8 @@ public class AlbumBottomSheetDialog extends BottomSheetDialogFragment implements albumBottomSheetViewModel = new ViewModelProvider(requireActivity()).get(AlbumBottomSheetViewModel.class); albumBottomSheetViewModel.setAlbum(album); + songRepository = new SongRepository(App.getInstance()); + init(view); return view; @@ -74,19 +85,26 @@ public class AlbumBottomSheetDialog extends BottomSheetDialogFragment implements playRandom = view.findViewById(R.id.play_random_text_view); playRandom.setOnClickListener(v -> { - Toast.makeText(requireContext(), "Play next", Toast.LENGTH_SHORT).show(); + List songs = songRepository.getAlbumListSong(album.getId(), true); + + QueueRepository queueRepository = new QueueRepository(App.getInstance()); + queueRepository.insertAllAndStartNew(songs); + + MusicPlayerRemote.openQueue(songs, 0, true); + ((MainActivity) requireActivity()).isBottomSheetInPeek(true); dismissBottomSheet(); }); playNext = view.findViewById(R.id.play_next_text_view); playNext.setOnClickListener(v -> { - Toast.makeText(requireContext(), "Play next", Toast.LENGTH_SHORT).show(); + MusicPlayerRemote.playNext(songRepository.getAlbumListSong(album.getId(), false)); + ((MainActivity) requireActivity()).isBottomSheetInPeek(true); dismissBottomSheet(); }); addToQueue = view.findViewById(R.id.add_to_queue_text_view); addToQueue.setOnClickListener(v -> { - Toast.makeText(requireContext(), "Add to queue", Toast.LENGTH_SHORT).show(); + MusicPlayerRemote.enqueue(songRepository.getAlbumListSong(album.getId(), false)); dismissBottomSheet(); }); diff --git a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/SongBottomSheetDialog.java b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/SongBottomSheetDialog.java index 3ad0dbbe..31226113 100644 --- a/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/SongBottomSheetDialog.java +++ b/app/src/main/java/com/cappielloantonio/play/ui/fragment/bottomsheetdialog/SongBottomSheetDialog.java @@ -15,12 +15,17 @@ import androidx.navigation.fragment.NavHostFragment; import com.cappielloantonio.play.R; import com.cappielloantonio.play.glide.CustomGlideRequest; +import com.cappielloantonio.play.helper.MusicPlayerRemote; import com.cappielloantonio.play.model.Album; import com.cappielloantonio.play.model.Artist; import com.cappielloantonio.play.model.Song; +import com.cappielloantonio.play.ui.activities.MainActivity; +import com.cappielloantonio.play.viewmodel.PlayerBottomSheetViewModel; import com.cappielloantonio.play.viewmodel.SongBottomSheetViewModel; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import java.util.Objects; + public class SongBottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener { private static final String TAG = "SongBottomSheetDialog"; @@ -84,13 +89,15 @@ public class SongBottomSheetDialog extends BottomSheetDialogFragment implements playNext = view.findViewById(R.id.play_next_text_view); playNext.setOnClickListener(v -> { - Toast.makeText(requireContext(), "Play next", Toast.LENGTH_SHORT).show(); + MusicPlayerRemote.playNext(song); + ((MainActivity) requireActivity()).isBottomSheetInPeek(true); dismissBottomSheet(); }); addToQueue = view.findViewById(R.id.add_to_queue_text_view); addToQueue.setOnClickListener(v -> { - Toast.makeText(requireContext(), "Add to queue", Toast.LENGTH_SHORT).show(); + MusicPlayerRemote.enqueue(song); + ((MainActivity) requireActivity()).isBottomSheetInPeek(true); dismissBottomSheet(); }); diff --git a/app/src/main/java/com/cappielloantonio/play/util/QueueUtil.java b/app/src/main/java/com/cappielloantonio/play/util/QueueUtil.java index 30d75f12..ef8c310f 100644 --- a/app/src/main/java/com/cappielloantonio/play/util/QueueUtil.java +++ b/app/src/main/java/com/cappielloantonio/play/util/QueueUtil.java @@ -8,7 +8,11 @@ import java.util.List; public class QueueUtil { public static Queue getQueueElementFromSong(Song song) { - return new Queue(song.getId(), 0); + return new Queue(0, song.getId()); + } + + public static Queue getQueueElementFromSong(Song song, int startingPosition) { + return new Queue(startingPosition, song.getId()); } public static List getQueueElementsFromSongs(List songs) { @@ -16,7 +20,19 @@ public class QueueUtil { List queue = new ArrayList<>(); for(Song song: songs) { - queue.add(new Queue(song.getId(), counter)); + queue.add(new Queue(counter, song.getId())); + counter++; + } + + return queue; + } + + public static List getQueueElementsFromSongs(List songs, int startingPosition) { + int counter = startingPosition; + List queue = new ArrayList<>(); + + for(Song song: songs) { + queue.add(new Queue(counter, song.getId())); counter++; }