Added song InstantMix

This commit is contained in:
CappielloAntonio 2021-04-18 20:23:09 +02:00
parent fc430e5811
commit 7576fbb75b
8 changed files with 169 additions and 8 deletions

View file

@ -1,6 +1,7 @@
package com.cappielloantonio.play.adapter; package com.cappielloantonio.play.adapter;
import android.content.Context; import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -8,14 +9,22 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.cappielloantonio.play.App; import com.cappielloantonio.play.App;
import com.cappielloantonio.play.R; import com.cappielloantonio.play.R;
import com.cappielloantonio.play.glide.CustomGlideRequest; import com.cappielloantonio.play.glide.CustomGlideRequest;
import com.cappielloantonio.play.helper.MusicPlayerRemote;
import com.cappielloantonio.play.interfaces.MediaCallback;
import com.cappielloantonio.play.model.Song; import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.QueueRepository;
import com.cappielloantonio.play.repository.SongRepository; import com.cappielloantonio.play.repository.SongRepository;
import com.cappielloantonio.play.ui.activities.MainActivity;
import com.cappielloantonio.play.util.SyncUtil;
import com.cappielloantonio.play.viewmodel.PlayerBottomSheetViewModel;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class DiscoverSongAdapter extends RecyclerView.Adapter<DiscoverSongAdapter.ViewHolder> { public class DiscoverSongAdapter extends RecyclerView.Adapter<DiscoverSongAdapter.ViewHolder> {
@ -24,8 +33,10 @@ public class DiscoverSongAdapter extends RecyclerView.Adapter<DiscoverSongAdapte
private List<Song> songs; private List<Song> songs;
private LayoutInflater inflater; private LayoutInflater inflater;
private Context context; private Context context;
private MainActivity activity;
public DiscoverSongAdapter(Context context, List<Song> songs) { public DiscoverSongAdapter(MainActivity activity, Context context, List<Song> songs) {
this.activity = activity;
this.context = context; this.context = context;
this.inflater = LayoutInflater.from(context); this.inflater = LayoutInflater.from(context);
this.songs = songs; this.songs = songs;
@ -72,7 +83,27 @@ public class DiscoverSongAdapter extends RecyclerView.Adapter<DiscoverSongAdapte
@Override @Override
public void onClick(View view) { public void onClick(View view) {
Toast.makeText(context, "Ongoing development", Toast.LENGTH_SHORT).show(); SyncUtil.getInstantMix(context, new MediaCallback() {
@Override
public void onError(Exception exception) {
Log.e(TAG, "onError: " + exception.getMessage());
}
@Override
public void onLoadMedia(List<?> media) {
QueueRepository queueRepository = new QueueRepository(App.getInstance());
queueRepository.insertAllAndStartNew((ArrayList<Song>) media);
activity.isBottomSheetInPeek(true);
activity.setBottomSheetMusicInfo(((ArrayList<Song>) media).get(0));
PlayerBottomSheetViewModel playerBottomSheetViewModel = new ViewModelProvider(activity).get(PlayerBottomSheetViewModel.class);
playerBottomSheetViewModel.setNowPlayingSong(((ArrayList<Song>) media).get(0));
MusicPlayerRemote.openQueue((ArrayList<Song>) media, 0, true);
}
}, SyncUtil.SONG, songs.get(getBindingAdapterPosition()).getId(), 50);
} }
} }

View file

@ -48,6 +48,9 @@ public class Song implements Parcelable {
@Ignore @Ignore
public static final String IS_FAVORITE = "IS_FAVORITE"; public static final String IS_FAVORITE = "IS_FAVORITE";
@Ignore
public static final String RADIO = "RADIO";
/* /*
* TODO: Da capire chi tra albumArtist e artistItems sono i compositori e suonatori dell'album, oppure le comparse * TODO: Da capire chi tra albumArtist e artistItems sono i compositori e suonatori dell'album, oppure le comparse
* In teoria AlbumArtist sono i creatori, mentre ArtistItems le comparse * In teoria AlbumArtist sono i creatori, mentre ArtistItems le comparse

View file

@ -103,7 +103,7 @@ public class HomeFragment extends Fragment {
private void initDiscoverSongSlideView() { private void initDiscoverSongSlideView() {
bind.discoverSongViewPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL); bind.discoverSongViewPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
discoverSongAdapter = new DiscoverSongAdapter(requireContext(), homeViewModel.getDiscoverSongList()); discoverSongAdapter = new DiscoverSongAdapter(activity, requireContext(), homeViewModel.getDiscoverSongList());
bind.discoverSongViewPager.setAdapter(discoverSongAdapter); bind.discoverSongViewPager.setAdapter(discoverSongAdapter);
bind.discoverSongViewPager.setOffscreenPageLimit(3); bind.discoverSongViewPager.setOffscreenPageLimit(3);
setDiscoverSongSlideViewOffset(20, 16); setDiscoverSongSlideViewOffset(20, 16);

View file

@ -87,6 +87,11 @@ public class SongListPageFragment extends Fragment {
songListPageViewModel.title = Song.IS_FAVORITE; songListPageViewModel.title = Song.IS_FAVORITE;
bind.pageTitleLabel.setText("Favourite song"); bind.pageTitleLabel.setText("Favourite song");
} }
else if(getArguments().getString(Song.RADIO) != null) {
songListPageViewModel.title = Song.IS_FAVORITE;
songListPageViewModel.year = getArguments().getInt("radio_object");
bind.pageTitleLabel.setText("Radio");
}
} }
private void initSongListView() { private void initSongListView() {

View file

@ -1,6 +1,7 @@
package com.cappielloantonio.play.ui.fragment.bottomsheetdialog; package com.cappielloantonio.play.ui.fragment.bottomsheetdialog;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -16,15 +17,19 @@ import com.cappielloantonio.play.App;
import com.cappielloantonio.play.R; import com.cappielloantonio.play.R;
import com.cappielloantonio.play.glide.CustomGlideRequest; import com.cappielloantonio.play.glide.CustomGlideRequest;
import com.cappielloantonio.play.helper.MusicPlayerRemote; import com.cappielloantonio.play.helper.MusicPlayerRemote;
import com.cappielloantonio.play.interfaces.MediaCallback;
import com.cappielloantonio.play.model.Album; import com.cappielloantonio.play.model.Album;
import com.cappielloantonio.play.model.Artist; import com.cappielloantonio.play.model.Artist;
import com.cappielloantonio.play.model.Song; import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.QueueRepository; import com.cappielloantonio.play.repository.QueueRepository;
import com.cappielloantonio.play.repository.SongRepository; import com.cappielloantonio.play.repository.SongRepository;
import com.cappielloantonio.play.ui.activities.MainActivity; import com.cappielloantonio.play.ui.activities.MainActivity;
import com.cappielloantonio.play.util.SyncUtil;
import com.cappielloantonio.play.viewmodel.AlbumBottomSheetViewModel; import com.cappielloantonio.play.viewmodel.AlbumBottomSheetViewModel;
import com.cappielloantonio.play.viewmodel.PlayerBottomSheetViewModel;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class AlbumBottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener { public class AlbumBottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener {
@ -79,7 +84,29 @@ public class AlbumBottomSheetDialog extends BottomSheetDialogFragment implements
playRadio = view.findViewById(R.id.play_radio_text_view); playRadio = view.findViewById(R.id.play_radio_text_view);
playRadio.setOnClickListener(v -> { playRadio.setOnClickListener(v -> {
Toast.makeText(requireContext(), "Play radio", Toast.LENGTH_SHORT).show(); SyncUtil.getInstantMix(requireContext(), new MediaCallback() {
MainActivity activity = (MainActivity) requireActivity();
@Override
public void onError(Exception exception) {
Log.e(TAG, "onError: " + exception.getMessage());
}
@Override
public void onLoadMedia(List<?> media) {
QueueRepository queueRepository = new QueueRepository(App.getInstance());
queueRepository.insertAllAndStartNew((ArrayList<Song>) media);
activity.isBottomSheetInPeek(true);
activity.setBottomSheetMusicInfo(((ArrayList<Song>) media).get(0));
PlayerBottomSheetViewModel playerBottomSheetViewModel = new ViewModelProvider(activity).get(PlayerBottomSheetViewModel.class);
playerBottomSheetViewModel.setNowPlayingSong(((ArrayList<Song>) media).get(0));
MusicPlayerRemote.openQueue((ArrayList<Song>) media, 0, true);
}
}, SyncUtil.SONG, album.getId(), 50);
dismissBottomSheet(); dismissBottomSheet();
}); });

View file

@ -16,14 +16,18 @@ import com.cappielloantonio.play.App;
import com.cappielloantonio.play.R; import com.cappielloantonio.play.R;
import com.cappielloantonio.play.glide.CustomGlideRequest; import com.cappielloantonio.play.glide.CustomGlideRequest;
import com.cappielloantonio.play.helper.MusicPlayerRemote; import com.cappielloantonio.play.helper.MusicPlayerRemote;
import com.cappielloantonio.play.interfaces.MediaCallback;
import com.cappielloantonio.play.model.Artist; import com.cappielloantonio.play.model.Artist;
import com.cappielloantonio.play.model.Song; import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.QueueRepository; import com.cappielloantonio.play.repository.QueueRepository;
import com.cappielloantonio.play.repository.SongRepository; import com.cappielloantonio.play.repository.SongRepository;
import com.cappielloantonio.play.ui.activities.MainActivity; import com.cappielloantonio.play.ui.activities.MainActivity;
import com.cappielloantonio.play.util.SyncUtil;
import com.cappielloantonio.play.viewmodel.ArtistBottomSheetViewModel; import com.cappielloantonio.play.viewmodel.ArtistBottomSheetViewModel;
import com.cappielloantonio.play.viewmodel.PlayerBottomSheetViewModel;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class ArtistBottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener { public class ArtistBottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener {
@ -69,7 +73,29 @@ public class ArtistBottomSheetDialog extends BottomSheetDialogFragment implement
playRadio = view.findViewById(R.id.play_radio_text_view); playRadio = view.findViewById(R.id.play_radio_text_view);
playRadio.setOnClickListener(v -> { playRadio.setOnClickListener(v -> {
Toast.makeText(requireContext(), "Play radio", Toast.LENGTH_SHORT).show(); SyncUtil.getInstantMix(requireContext(), new MediaCallback() {
MainActivity activity = (MainActivity) requireActivity();
@Override
public void onError(Exception exception) {
Log.e(TAG, "onError: " + exception.getMessage());
}
@Override
public void onLoadMedia(List<?> media) {
QueueRepository queueRepository = new QueueRepository(App.getInstance());
queueRepository.insertAllAndStartNew((ArrayList<Song>) media);
activity.isBottomSheetInPeek(true);
activity.setBottomSheetMusicInfo(((ArrayList<Song>) media).get(0));
PlayerBottomSheetViewModel playerBottomSheetViewModel = new ViewModelProvider(activity).get(PlayerBottomSheetViewModel.class);
playerBottomSheetViewModel.setNowPlayingSong(((ArrayList<Song>) media).get(0));
MusicPlayerRemote.openQueue((ArrayList<Song>) media, 0, true);
}
}, SyncUtil.SONG, artist.getId(), 50);
dismissBottomSheet(); dismissBottomSheet();
}); });

View file

@ -1,6 +1,7 @@
package com.cappielloantonio.play.ui.fragment.bottomsheetdialog; package com.cappielloantonio.play.ui.fragment.bottomsheetdialog;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -13,17 +14,24 @@ import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.fragment.NavHostFragment; import androidx.navigation.fragment.NavHostFragment;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.R; import com.cappielloantonio.play.R;
import com.cappielloantonio.play.glide.CustomGlideRequest; import com.cappielloantonio.play.glide.CustomGlideRequest;
import com.cappielloantonio.play.helper.MusicPlayerRemote; import com.cappielloantonio.play.helper.MusicPlayerRemote;
import com.cappielloantonio.play.interfaces.MediaCallback;
import com.cappielloantonio.play.model.Album; import com.cappielloantonio.play.model.Album;
import com.cappielloantonio.play.model.Artist; import com.cappielloantonio.play.model.Artist;
import com.cappielloantonio.play.model.PlaylistSongCross;
import com.cappielloantonio.play.model.Song; import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.QueueRepository;
import com.cappielloantonio.play.ui.activities.MainActivity; import com.cappielloantonio.play.ui.activities.MainActivity;
import com.cappielloantonio.play.util.SyncUtil;
import com.cappielloantonio.play.viewmodel.PlayerBottomSheetViewModel; import com.cappielloantonio.play.viewmodel.PlayerBottomSheetViewModel;
import com.cappielloantonio.play.viewmodel.SongBottomSheetViewModel; import com.cappielloantonio.play.viewmodel.SongBottomSheetViewModel;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects; import java.util.Objects;
public class SongBottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener { public class SongBottomSheetDialog extends BottomSheetDialogFragment implements View.OnClickListener {
@ -83,7 +91,29 @@ public class SongBottomSheetDialog extends BottomSheetDialogFragment implements
playRadio = view.findViewById(R.id.play_radio_text_view); playRadio = view.findViewById(R.id.play_radio_text_view);
playRadio.setOnClickListener(v -> { playRadio.setOnClickListener(v -> {
Toast.makeText(requireContext(), "Play radio", Toast.LENGTH_SHORT).show(); SyncUtil.getInstantMix(requireContext(), new MediaCallback() {
MainActivity activity = (MainActivity) requireActivity();
@Override
public void onError(Exception exception) {
Log.e(TAG, "onError: " + exception.getMessage());
}
@Override
public void onLoadMedia(List<?> media) {
QueueRepository queueRepository = new QueueRepository(App.getInstance());
queueRepository.insertAllAndStartNew((ArrayList<Song>) media);
activity.isBottomSheetInPeek(true);
activity.setBottomSheetMusicInfo(((ArrayList<Song>) media).get(0));
PlayerBottomSheetViewModel playerBottomSheetViewModel = new ViewModelProvider(activity).get(PlayerBottomSheetViewModel.class);
playerBottomSheetViewModel.setNowPlayingSong(((ArrayList<Song>) media).get(0));
MusicPlayerRemote.openQueue((ArrayList<Song>) media, 0, true);
}
}, SyncUtil.SONG, song.getId(), 50);
dismissBottomSheet(); dismissBottomSheet();
}); });

View file

@ -2,7 +2,6 @@ package com.cappielloantonio.play.util;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import com.cappielloantonio.play.App; import com.cappielloantonio.play.App;
import com.cappielloantonio.play.interfaces.MediaCallback; import com.cappielloantonio.play.interfaces.MediaCallback;
@ -16,12 +15,14 @@ import com.cappielloantonio.play.model.SongGenreCross;
import org.jellyfin.apiclient.interaction.Response; import org.jellyfin.apiclient.interaction.Response;
import org.jellyfin.apiclient.model.dto.BaseItemDto; import org.jellyfin.apiclient.model.dto.BaseItemDto;
import org.jellyfin.apiclient.model.dto.BaseItemType;
import org.jellyfin.apiclient.model.querying.ArtistsQuery; import org.jellyfin.apiclient.model.querying.ArtistsQuery;
import org.jellyfin.apiclient.model.querying.ItemFields; import org.jellyfin.apiclient.model.querying.ItemFields;
import org.jellyfin.apiclient.model.querying.ItemQuery; import org.jellyfin.apiclient.model.querying.ItemQuery;
import org.jellyfin.apiclient.model.querying.ItemsByNameQuery; import org.jellyfin.apiclient.model.querying.ItemsByNameQuery;
import org.jellyfin.apiclient.model.querying.ItemsResult; import org.jellyfin.apiclient.model.querying.ItemsResult;
import org.jellyfin.apiclient.model.playlists.PlaylistItemQuery; import org.jellyfin.apiclient.model.playlists.PlaylistItemQuery;
import org.jellyfin.apiclient.model.querying.SimilarItemsQuery;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -31,6 +32,10 @@ import java.util.Map;
public class SyncUtil { public class SyncUtil {
private static final String TAG = "SyncUtil"; private static final String TAG = "SyncUtil";
public static final String SONG = "song";
public static final String ALBUM = "album";
public static final String ARTIST = "artist";
public static void getLibraries(Context context, MediaCallback callback) { public static void getLibraries(Context context, MediaCallback callback) {
String id = App.getApiClientInstance(context).getCurrentUserId(); String id = App.getApiClientInstance(context).getCurrentUserId();
@ -216,7 +221,6 @@ public class SyncUtil {
query.setId(playlistId); query.setId(playlistId);
query.setUserId(App.getApiClientInstance(context).getCurrentUserId()); query.setUserId(App.getApiClientInstance(context).getCurrentUserId());
query.setFields(new ItemFields[]{ItemFields.MediaSources}); query.setFields(new ItemFields[]{ItemFields.MediaSources});
query.setUserId(App.getApiClientInstance(context).getCurrentUserId());
App.getApiClientInstance(context).GetPlaylistItems(query, new Response<ItemsResult>() { App.getApiClientInstance(context).GetPlaylistItems(query, new Response<ItemsResult>() {
@ -238,6 +242,41 @@ public class SyncUtil {
}); });
} }
public static void getInstantMix(Context context, MediaCallback callback, String resultType, String itemID, int limit) {
SimilarItemsQuery query = new SimilarItemsQuery();
query.setId(itemID);
query.setUserId(App.getApiClientInstance(context).getCurrentUserId());
query.setFields(new ItemFields[]{ItemFields.MediaSources});
query.setLimit(limit);
App.getApiClientInstance(context).GetInstantMixFromItem(query, new Response<ItemsResult>() {
@Override
public void onResponse(ItemsResult result) {
List<Object> items = new ArrayList<>();
for (BaseItemDto itemDto : result.getItems()) {
if (resultType.equals(ARTIST) && itemDto.getBaseItemType() == BaseItemType.MusicArtist) {
items.add(new Artist(itemDto));
}
else if (resultType.equals(ALBUM) && itemDto.getBaseItemType() == BaseItemType.MusicAlbum) {
items.add(new Album(itemDto));
}
else if (resultType.equals(SONG) && itemDto.getBaseItemType() == BaseItemType.Audio) {
items.add(new Song(itemDto));
}
}
callback.onLoadMedia(items);
}
@Override
public void onError(Exception exception) {
callback.onError(exception);
}
});
}
public static Bundle getSyncBundle(Boolean syncAlbum, Boolean syncArtist, Boolean syncGenres, Boolean syncPlaylist, Boolean syncSong, Boolean crossSyncSongGenre) { public static Bundle getSyncBundle(Boolean syncAlbum, Boolean syncArtist, Boolean syncGenres, Boolean syncPlaylist, Boolean syncSong, Boolean crossSyncSongGenre) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putBoolean("sync_album", syncAlbum); bundle.putBoolean("sync_album", syncAlbum);