mirror of
https://github.com/antebudimir/tempus.git
synced 2025-12-31 17:43:32 +00:00
Removed almost all hardcoded constants and deleted offline playlist model
This commit is contained in:
parent
e98429503b
commit
ff1a1350f9
24 changed files with 64 additions and 380 deletions
|
|
@ -10,7 +10,6 @@ import com.cappielloantonio.play.App;
|
||||||
import com.cappielloantonio.play.database.converter.DateConverters;
|
import com.cappielloantonio.play.database.converter.DateConverters;
|
||||||
import com.cappielloantonio.play.database.dao.ChronologyDao;
|
import com.cappielloantonio.play.database.dao.ChronologyDao;
|
||||||
import com.cappielloantonio.play.database.dao.DownloadDao;
|
import com.cappielloantonio.play.database.dao.DownloadDao;
|
||||||
import com.cappielloantonio.play.database.dao.PlaylistDao;
|
|
||||||
import com.cappielloantonio.play.database.dao.QueueDao;
|
import com.cappielloantonio.play.database.dao.QueueDao;
|
||||||
import com.cappielloantonio.play.database.dao.RecentSearchDao;
|
import com.cappielloantonio.play.database.dao.RecentSearchDao;
|
||||||
import com.cappielloantonio.play.database.dao.ServerDao;
|
import com.cappielloantonio.play.database.dao.ServerDao;
|
||||||
|
|
@ -19,12 +18,11 @@ import com.cappielloantonio.play.model.Download;
|
||||||
import com.cappielloantonio.play.model.Queue;
|
import com.cappielloantonio.play.model.Queue;
|
||||||
import com.cappielloantonio.play.model.RecentSearch;
|
import com.cappielloantonio.play.model.RecentSearch;
|
||||||
import com.cappielloantonio.play.model.Server;
|
import com.cappielloantonio.play.model.Server;
|
||||||
import com.cappielloantonio.play.subsonic.models.Playlist;
|
|
||||||
|
|
||||||
@Database(
|
@Database(
|
||||||
version = 60,
|
version = 61,
|
||||||
entities = {Queue.class, Server.class, RecentSearch.class, Download.class, Playlist.class, Chronology.class},
|
entities = {Queue.class, Server.class, RecentSearch.class, Download.class, Chronology.class},
|
||||||
autoMigrations = {@AutoMigration(from = 59, to = 60)}
|
autoMigrations = {@AutoMigration(from = 60, to = 61)}
|
||||||
)
|
)
|
||||||
@TypeConverters({DateConverters.class})
|
@TypeConverters({DateConverters.class})
|
||||||
public abstract class AppDatabase extends RoomDatabase {
|
public abstract class AppDatabase extends RoomDatabase {
|
||||||
|
|
@ -49,7 +47,5 @@ public abstract class AppDatabase extends RoomDatabase {
|
||||||
|
|
||||||
public abstract DownloadDao downloadDao();
|
public abstract DownloadDao downloadDao();
|
||||||
|
|
||||||
public abstract PlaylistDao playlistDao();
|
|
||||||
|
|
||||||
public abstract ChronologyDao chronologyDao();
|
public abstract ChronologyDao chronologyDao();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,9 @@ package com.cappielloantonio.play.repository;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.lifecycle.LiveData;
|
|
||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
import com.cappielloantonio.play.App;
|
import com.cappielloantonio.play.App;
|
||||||
import com.cappielloantonio.play.database.AppDatabase;
|
|
||||||
import com.cappielloantonio.play.database.dao.PlaylistDao;
|
|
||||||
import com.cappielloantonio.play.subsonic.base.ApiResponse;
|
import com.cappielloantonio.play.subsonic.base.ApiResponse;
|
||||||
import com.cappielloantonio.play.subsonic.models.Child;
|
import com.cappielloantonio.play.subsonic.models.Child;
|
||||||
import com.cappielloantonio.play.subsonic.models.Playlist;
|
import com.cappielloantonio.play.subsonic.models.Playlist;
|
||||||
|
|
@ -22,8 +19,6 @@ import retrofit2.Callback;
|
||||||
import retrofit2.Response;
|
import retrofit2.Response;
|
||||||
|
|
||||||
public class PlaylistRepository {
|
public class PlaylistRepository {
|
||||||
private final PlaylistDao playlistDao = AppDatabase.getInstance().playlistDao();
|
|
||||||
|
|
||||||
public MutableLiveData<List<Playlist>> getPlaylists(boolean random, int size) {
|
public MutableLiveData<List<Playlist>> getPlaylists(boolean random, int size) {
|
||||||
MutableLiveData<List<Playlist>> listLivePlaylists = new MutableLiveData<>(new ArrayList<>());
|
MutableLiveData<List<Playlist>> listLivePlaylists = new MutableLiveData<>(new ArrayList<>());
|
||||||
|
|
||||||
|
|
@ -143,51 +138,4 @@ public class PlaylistRepository {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<Playlist>> getPinnedPlaylists(String serverId) {
|
|
||||||
// return playlistDao.getAll(serverId);
|
|
||||||
return playlistDao.getAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void insert(Playlist playlist) {
|
|
||||||
InsertThreadSafe insert = new InsertThreadSafe(playlistDao, playlist);
|
|
||||||
Thread thread = new Thread(insert);
|
|
||||||
thread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete(Playlist playlist) {
|
|
||||||
DeleteThreadSafe delete = new DeleteThreadSafe(playlistDao, playlist);
|
|
||||||
Thread thread = new Thread(delete);
|
|
||||||
thread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class InsertThreadSafe implements Runnable {
|
|
||||||
private final PlaylistDao playlistDao;
|
|
||||||
private final Playlist playlist;
|
|
||||||
|
|
||||||
public InsertThreadSafe(PlaylistDao playlistDao, Playlist playlist) {
|
|
||||||
this.playlistDao = playlistDao;
|
|
||||||
this.playlist = playlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
playlistDao.insert(playlist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class DeleteThreadSafe implements Runnable {
|
|
||||||
private final PlaylistDao playlistDao;
|
|
||||||
private final Playlist playlist;
|
|
||||||
|
|
||||||
public DeleteThreadSafe(PlaylistDao playlistDao, Playlist playlist) {
|
|
||||||
this.playlistDao = playlistDao;
|
|
||||||
this.playlist = playlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
playlistDao.delete(playlist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,8 +96,8 @@ public class ArtistAdapter extends RecyclerView.Adapter<ArtistAdapter.ViewHolder
|
||||||
public void onClick() {
|
public void onClick() {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putParcelable(Constants.ARTIST_OBJECT, artists.get(getBindingAdapterPosition()));
|
bundle.putParcelable(Constants.ARTIST_OBJECT, artists.get(getBindingAdapterPosition()));
|
||||||
bundle.putBoolean("is_mix", mix);
|
bundle.putBoolean(Constants.MEDIA_MIX, mix);
|
||||||
bundle.putBoolean("is_best_of", bestOf);
|
bundle.putBoolean(Constants.MEDIA_BEST_OF, bestOf);
|
||||||
|
|
||||||
click.onArtistClick(bundle);
|
click.onArtistClick(bundle);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ public class DiscoverSongAdapter extends RecyclerView.Adapter<DiscoverSongAdapte
|
||||||
public void onClick() {
|
public void onClick() {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putParcelable(Constants.TRACK_OBJECT, songs.get(getBindingAdapterPosition()));
|
bundle.putParcelable(Constants.TRACK_OBJECT, songs.get(getBindingAdapterPosition()));
|
||||||
bundle.putBoolean("is_mix", true);
|
bundle.putBoolean(Constants.MEDIA_MIX, true);
|
||||||
|
|
||||||
click.onMediaClick(bundle);
|
click.onMediaClick(bundle);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ public class GenreAdapter extends RecyclerView.Adapter<GenreAdapter.ViewHolder>
|
||||||
|
|
||||||
private void onClick() {
|
private void onClick() {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putString(Constants.MEDIA_BY_GENRES, Constants.MEDIA_BY_GENRE);
|
bundle.putString(Constants.MEDIA_BY_GENRE, Constants.MEDIA_BY_GENRE);
|
||||||
bundle.putParcelable(Constants.GENRE_OBJECT, genres.get(getBindingAdapterPosition()));
|
bundle.putParcelable(Constants.GENRE_OBJECT, genres.get(getBindingAdapterPosition()));
|
||||||
|
|
||||||
click.onGenreClick(bundle);
|
click.onGenreClick(bundle);
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ public class GridTrackAdapter extends RecyclerView.Adapter<GridTrackAdapter.View
|
||||||
public void onClick() {
|
public void onClick() {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putParcelableArrayList(Constants.TRACKS_OBJECT, new ArrayList<>(items));
|
bundle.putParcelableArrayList(Constants.TRACKS_OBJECT, new ArrayList<>(items));
|
||||||
bundle.putBoolean("is_chronology", true);
|
bundle.putBoolean(Constants.MEDIA_CHRONOLOGY, true);
|
||||||
bundle.putInt(Constants.ITEM_POSITION, getBindingAdapterPosition());
|
bundle.putInt(Constants.ITEM_POSITION, getBindingAdapterPosition());
|
||||||
|
|
||||||
click.onMediaClick(bundle);
|
click.onMediaClick(bundle);
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import com.cappielloantonio.play.databinding.ItemHomePodcastEpisodeBinding;
|
||||||
import com.cappielloantonio.play.glide.CustomGlideRequest;
|
import com.cappielloantonio.play.glide.CustomGlideRequest;
|
||||||
import com.cappielloantonio.play.interfaces.ClickCallback;
|
import com.cappielloantonio.play.interfaces.ClickCallback;
|
||||||
import com.cappielloantonio.play.subsonic.models.PodcastEpisode;
|
import com.cappielloantonio.play.subsonic.models.PodcastEpisode;
|
||||||
|
import com.cappielloantonio.play.util.Constants;
|
||||||
import com.cappielloantonio.play.util.MusicUtil;
|
import com.cappielloantonio.play.util.MusicUtil;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
|
@ -79,14 +80,14 @@ public class PodcastEpisodeAdapter extends RecyclerView.Adapter<PodcastEpisodeAd
|
||||||
|
|
||||||
public void onClick() {
|
public void onClick() {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putParcelable("podcast_object", podcastEpisodes.get(getBindingAdapterPosition()));
|
bundle.putParcelable(Constants.PODCAST_OBJECT, podcastEpisodes.get(getBindingAdapterPosition()));
|
||||||
|
|
||||||
click.onPodcastClick(bundle);
|
click.onPodcastClick(bundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean openMore() {
|
private boolean openMore() {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putParcelable("podcast_object", podcastEpisodes.get(getBindingAdapterPosition()));
|
bundle.putParcelable(Constants.PODCAST_OBJECT, podcastEpisodes.get(getBindingAdapterPosition()));
|
||||||
|
|
||||||
click.onPodcastLongClick(bundle);
|
click.onPodcastLongClick(bundle);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ public class SimilarTrackAdapter extends RecyclerView.Adapter<SimilarTrackAdapte
|
||||||
public void onClick() {
|
public void onClick() {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putParcelable(Constants.TRACK_OBJECT, songs.get(getBindingAdapterPosition()));
|
bundle.putParcelable(Constants.TRACK_OBJECT, songs.get(getBindingAdapterPosition()));
|
||||||
bundle.putBoolean("is_mix", true);
|
bundle.putBoolean(Constants.MEDIA_MIX, true);
|
||||||
|
|
||||||
click.onMediaClick(bundle);
|
click.onMediaClick(bundle);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
@ -22,7 +21,6 @@ import androidx.navigation.Navigation;
|
||||||
import androidx.recyclerview.widget.GridLayoutManager;
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.PagerSnapHelper;
|
import androidx.recyclerview.widget.PagerSnapHelper;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
import androidx.recyclerview.widget.SnapHelper;
|
import androidx.recyclerview.widget.SnapHelper;
|
||||||
import androidx.viewpager2.widget.ViewPager2;
|
import androidx.viewpager2.widget.ViewPager2;
|
||||||
|
|
||||||
|
|
@ -35,7 +33,6 @@ import com.cappielloantonio.play.interfaces.ClickCallback;
|
||||||
import com.cappielloantonio.play.service.MediaManager;
|
import com.cappielloantonio.play.service.MediaManager;
|
||||||
import com.cappielloantonio.play.service.MediaService;
|
import com.cappielloantonio.play.service.MediaService;
|
||||||
import com.cappielloantonio.play.subsonic.models.Child;
|
import com.cappielloantonio.play.subsonic.models.Child;
|
||||||
import com.cappielloantonio.play.subsonic.models.Playlist;
|
|
||||||
import com.cappielloantonio.play.ui.activity.MainActivity;
|
import com.cappielloantonio.play.ui.activity.MainActivity;
|
||||||
import com.cappielloantonio.play.ui.adapter.AlbumAdapter;
|
import com.cappielloantonio.play.ui.adapter.AlbumAdapter;
|
||||||
import com.cappielloantonio.play.ui.adapter.AlbumHorizontalAdapter;
|
import com.cappielloantonio.play.ui.adapter.AlbumHorizontalAdapter;
|
||||||
|
|
@ -48,7 +45,6 @@ import com.cappielloantonio.play.ui.adapter.SimilarTrackAdapter;
|
||||||
import com.cappielloantonio.play.ui.adapter.SongHorizontalAdapter;
|
import com.cappielloantonio.play.ui.adapter.SongHorizontalAdapter;
|
||||||
import com.cappielloantonio.play.ui.adapter.YearAdapter;
|
import com.cappielloantonio.play.ui.adapter.YearAdapter;
|
||||||
import com.cappielloantonio.play.util.Constants;
|
import com.cappielloantonio.play.util.Constants;
|
||||||
import com.cappielloantonio.play.util.MusicUtil;
|
|
||||||
import com.cappielloantonio.play.util.UIUtil;
|
import com.cappielloantonio.play.util.UIUtil;
|
||||||
import com.cappielloantonio.play.viewmodel.HomeViewModel;
|
import com.cappielloantonio.play.viewmodel.HomeViewModel;
|
||||||
import com.google.android.gms.cast.framework.CastButtonFactory;
|
import com.google.android.gms.cast.framework.CastButtonFactory;
|
||||||
|
|
@ -127,7 +123,6 @@ public class HomeFragment extends Fragment implements ClickCallback {
|
||||||
initNewReleasesView();
|
initNewReleasesView();
|
||||||
initYearSongView();
|
initYearSongView();
|
||||||
initRecentAddedAlbumView();
|
initRecentAddedAlbumView();
|
||||||
initPinnedPlaylistsView();
|
|
||||||
initNewestPodcastsView();
|
initNewestPodcastsView();
|
||||||
initGridView();
|
initGridView();
|
||||||
}
|
}
|
||||||
|
|
@ -599,62 +594,6 @@ public class HomeFragment extends Fragment implements ClickCallback {
|
||||||
recentAddedAlbumSnapHelper.attachToRecyclerView(bind.recentlyAddedAlbumsRecyclerView);
|
recentAddedAlbumSnapHelper.attachToRecyclerView(bind.recentlyAddedAlbumsRecyclerView);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initPinnedPlaylistsView() {
|
|
||||||
homeViewModel.getPinnedPlaylistList(getViewLifecycleOwner(), 5, true).observe(getViewLifecycleOwner(), playlists -> {
|
|
||||||
if (bind != null && playlists != null) {
|
|
||||||
for (Playlist playlist : playlists) {
|
|
||||||
int playlistViewHashCode = playlist.getId().hashCode();
|
|
||||||
if (requireView().findViewById(playlistViewHashCode) == null) {
|
|
||||||
View genericPlaylistView = activity.getLayoutInflater().inflate(R.layout.generic_playlist_sector, null);
|
|
||||||
genericPlaylistView.setId(playlistViewHashCode);
|
|
||||||
genericPlaylistView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
|
||||||
|
|
||||||
TextView genericPlaylistTitleTextView = genericPlaylistView.findViewById(R.id.generic_playlist_title_text_view);
|
|
||||||
TextView genericPlaylistCickableTextView = genericPlaylistView.findViewById(R.id.generic_playlist_text_view_clickable);
|
|
||||||
RecyclerView genericPlaylistRecyclerView = genericPlaylistView.findViewById(R.id.generic_playlist_recycler_view);
|
|
||||||
|
|
||||||
genericPlaylistTitleTextView.setText(MusicUtil.getReadableString(playlist.getName()));
|
|
||||||
genericPlaylistRecyclerView.setHasFixedSize(true);
|
|
||||||
|
|
||||||
SongHorizontalAdapter trackAdapter = new SongHorizontalAdapter(this, true);
|
|
||||||
genericPlaylistRecyclerView.setAdapter(trackAdapter);
|
|
||||||
|
|
||||||
homeViewModel.getPlaylistSongLiveList(playlist.getId()).observe(getViewLifecycleOwner(), songs -> {
|
|
||||||
if (songs.size() > 0) {
|
|
||||||
int songsNumber = Math.min(20, songs.size());
|
|
||||||
|
|
||||||
genericPlaylistRecyclerView.setLayoutManager(new GridLayoutManager(requireContext(), UIUtil.getSpanCount(songsNumber, 5), GridLayoutManager.HORIZONTAL, false));
|
|
||||||
trackAdapter.setItems(songs.subList(0, songsNumber));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
genericPlaylistCickableTextView.setOnClickListener(view -> {
|
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putParcelable(Constants.PLAYLIST_OBJECT, playlist);
|
|
||||||
bundle.putBoolean("is_offline", false);
|
|
||||||
activity.navController.navigate(R.id.action_homeFragment_to_playlistPageFragment, bundle);
|
|
||||||
});
|
|
||||||
|
|
||||||
SnapHelper genericPlaylistSnapHelper = new PagerSnapHelper();
|
|
||||||
genericPlaylistSnapHelper.attachToRecyclerView(genericPlaylistRecyclerView);
|
|
||||||
|
|
||||||
genericPlaylistRecyclerView.addItemDecoration(
|
|
||||||
new DotsIndicatorDecoration(
|
|
||||||
getResources().getDimensionPixelSize(R.dimen.radius),
|
|
||||||
getResources().getDimensionPixelSize(R.dimen.radius) * 4,
|
|
||||||
getResources().getDimensionPixelSize(R.dimen.dots_height),
|
|
||||||
requireContext().getResources().getColor(R.color.titleTextColor, null),
|
|
||||||
requireContext().getResources().getColor(R.color.titleTextColor, null))
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
bind.homeLinearLayoutContainer.addView(genericPlaylistView);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initNewestPodcastsView() {
|
private void initNewestPodcastsView() {
|
||||||
bind.newestPodcastsViewPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
|
bind.newestPodcastsViewPager.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
|
||||||
|
|
||||||
|
|
@ -740,7 +679,7 @@ public class HomeFragment extends Fragment implements ClickCallback {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMediaClick(Bundle bundle) {
|
public void onMediaClick(Bundle bundle) {
|
||||||
if (bundle.containsKey("is_mix")) {
|
if (bundle.containsKey(Constants.MEDIA_MIX)) {
|
||||||
MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), bundle.getParcelable(Constants.TRACK_OBJECT));
|
MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), bundle.getParcelable(Constants.TRACK_OBJECT));
|
||||||
activity.setBottomSheetInPeek(true);
|
activity.setBottomSheetInPeek(true);
|
||||||
|
|
||||||
|
|
@ -751,7 +690,7 @@ public class HomeFragment extends Fragment implements ClickCallback {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (bundle.containsKey("is_chronology")) {
|
} else if (bundle.containsKey(Constants.MEDIA_CHRONOLOGY)) {
|
||||||
List<Child> media = bundle.getParcelableArrayList(Constants.TRACKS_OBJECT);
|
List<Child> media = bundle.getParcelableArrayList(Constants.TRACKS_OBJECT);
|
||||||
MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), media, bundle.getInt(Constants.ITEM_POSITION));
|
MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), media, bundle.getInt(Constants.ITEM_POSITION));
|
||||||
activity.setBottomSheetInPeek(true);
|
activity.setBottomSheetInPeek(true);
|
||||||
|
|
@ -778,22 +717,22 @@ public class HomeFragment extends Fragment implements ClickCallback {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onArtistClick(Bundle bundle) {
|
public void onArtistClick(Bundle bundle) {
|
||||||
if (bundle.containsKey("is_mix") && bundle.getBoolean("is_mix")) {
|
if (bundle.containsKey(Constants.MEDIA_MIX) && bundle.getBoolean(Constants.MEDIA_MIX)) {
|
||||||
Snackbar.make(requireView(), R.string.artist_adapter_radio_station_starting, Snackbar.LENGTH_LONG)
|
Snackbar.make(requireView(), R.string.artist_adapter_radio_station_starting, Snackbar.LENGTH_LONG)
|
||||||
.setAnchorView(activity.bind.playerBottomSheet)
|
.setAnchorView(activity.bind.playerBottomSheet)
|
||||||
.show();
|
.show();
|
||||||
|
|
||||||
if (mediaBrowserListenableFuture != null) {
|
if (mediaBrowserListenableFuture != null) {
|
||||||
homeViewModel.getArtistInstantMix(bundle.getParcelable(Constants.ARTIST_OBJECT)).observe(getViewLifecycleOwner(), songs -> {
|
homeViewModel.getArtistInstantMix(getViewLifecycleOwner(), bundle.getParcelable(Constants.ARTIST_OBJECT)).observe(getViewLifecycleOwner(), songs -> {
|
||||||
if (songs.size() > 0) {
|
if (songs.size() > 0) {
|
||||||
MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), songs, 0);
|
MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), songs, 0);
|
||||||
activity.setBottomSheetInPeek(true);
|
activity.setBottomSheetInPeek(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (bundle.containsKey("is_best_of") && bundle.getBoolean("is_best_of")) {
|
} else if (bundle.containsKey(Constants.MEDIA_BEST_OF) && bundle.getBoolean(Constants.MEDIA_BEST_OF)) {
|
||||||
if (mediaBrowserListenableFuture != null) {
|
if (mediaBrowserListenableFuture != null) {
|
||||||
homeViewModel.getArtistBestOf(bundle.getParcelable(Constants.ARTIST_OBJECT)).observe(getViewLifecycleOwner(), songs -> {
|
homeViewModel.getArtistBestOf(getViewLifecycleOwner(), bundle.getParcelable(Constants.ARTIST_OBJECT)).observe(getViewLifecycleOwner(), songs -> {
|
||||||
if (songs.size() > 0) {
|
if (songs.size() > 0) {
|
||||||
MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), songs, 0);
|
MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), songs, 0);
|
||||||
activity.setBottomSheetInPeek(true);
|
activity.setBottomSheetInPeek(true);
|
||||||
|
|
@ -817,7 +756,7 @@ public class HomeFragment extends Fragment implements ClickCallback {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPodcastClick(Bundle bundle) {
|
public void onPodcastClick(Bundle bundle) {
|
||||||
MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), bundle.getParcelable("podcast_object"));
|
MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), bundle.getParcelable(Constants.PODCAST_OBJECT));
|
||||||
activity.setBottomSheetInPeek(true);
|
activity.setBottomSheetInPeek(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -264,7 +264,6 @@ public class LibraryFragment extends Fragment implements ClickCallback {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlaylistClick(Bundle bundle) {
|
public void onPlaylistClick(Bundle bundle) {
|
||||||
bundle.putBoolean("is_offline", false);
|
|
||||||
Navigation.findNavController(requireView()).navigate(R.id.playlistPageFragment, bundle);
|
Navigation.findNavController(requireView()).navigate(R.id.playlistPageFragment, bundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,16 +26,12 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import com.cappielloantonio.play.R;
|
import com.cappielloantonio.play.R;
|
||||||
import com.cappielloantonio.play.databinding.FragmentPlaylistCatalogueBinding;
|
import com.cappielloantonio.play.databinding.FragmentPlaylistCatalogueBinding;
|
||||||
import com.cappielloantonio.play.interfaces.ClickCallback;
|
import com.cappielloantonio.play.interfaces.ClickCallback;
|
||||||
import com.cappielloantonio.play.subsonic.models.Playlist;
|
|
||||||
import com.cappielloantonio.play.ui.activity.MainActivity;
|
import com.cappielloantonio.play.ui.activity.MainActivity;
|
||||||
import com.cappielloantonio.play.ui.adapter.PlaylistHorizontalAdapter;
|
import com.cappielloantonio.play.ui.adapter.PlaylistHorizontalAdapter;
|
||||||
import com.cappielloantonio.play.ui.dialog.PlaylistEditorDialog;
|
import com.cappielloantonio.play.ui.dialog.PlaylistEditorDialog;
|
||||||
import com.cappielloantonio.play.util.Constants;
|
import com.cappielloantonio.play.util.Constants;
|
||||||
import com.cappielloantonio.play.viewmodel.PlaylistCatalogueViewModel;
|
import com.cappielloantonio.play.viewmodel.PlaylistCatalogueViewModel;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
public class PlaylistCatalogueFragment extends Fragment implements ClickCallback {
|
public class PlaylistCatalogueFragment extends Fragment implements ClickCallback {
|
||||||
private FragmentPlaylistCatalogueBinding bind;
|
private FragmentPlaylistCatalogueBinding bind;
|
||||||
|
|
@ -111,32 +107,7 @@ public class PlaylistCatalogueFragment extends Fragment implements ClickCallback
|
||||||
bind.playlistCatalogueRecyclerView.setAdapter(playlistHorizontalAdapter);
|
bind.playlistCatalogueRecyclerView.setAdapter(playlistHorizontalAdapter);
|
||||||
|
|
||||||
if (getActivity() != null) {
|
if (getActivity() != null) {
|
||||||
playlistCatalogueViewModel.getPlaylistList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), playlists ->
|
playlistCatalogueViewModel.getPlaylistList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), playlists -> playlistHorizontalAdapter.setItems(playlists));
|
||||||
playlistCatalogueViewModel.getPinnedPlaylistList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(),
|
|
||||||
pinnedPlaylists -> {
|
|
||||||
List<Playlist> sortedList = new ArrayList<>();
|
|
||||||
List<Playlist> unsortedList = new ArrayList<>(playlists);
|
|
||||||
|
|
||||||
List<Playlist> pinnedPlaylistsVerified = new ArrayList<>();
|
|
||||||
List<Playlist> pinnedPlaylistsNotFound = new ArrayList<>();
|
|
||||||
|
|
||||||
if (unsortedList.size() > 0) {
|
|
||||||
for (Playlist pinnedPlaylist : pinnedPlaylists) {
|
|
||||||
if (playlists.contains(pinnedPlaylist)) {
|
|
||||||
pinnedPlaylistsVerified.add(pinnedPlaylist);
|
|
||||||
} else {
|
|
||||||
pinnedPlaylistsNotFound.add(pinnedPlaylist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsortedList.removeAll(pinnedPlaylistsVerified);
|
|
||||||
sortedList.addAll(pinnedPlaylistsVerified);
|
|
||||||
sortedList.addAll(unsortedList);
|
|
||||||
}
|
|
||||||
|
|
||||||
playlistHorizontalAdapter.setItems(sortedList);
|
|
||||||
playlistCatalogueViewModel.unpinPlaylist(pinnedPlaylistsNotFound);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bind.playlistCatalogueRecyclerView.setOnTouchListener((v, event) -> {
|
bind.playlistCatalogueRecyclerView.setOnTouchListener((v, event) -> {
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@ public class PlaylistPageFragment extends Fragment implements ClickCallback {
|
||||||
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
|
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
|
||||||
super.onCreateOptionsMenu(menu, inflater);
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
inflater.inflate(R.menu.playlist_page_menu, menu);
|
inflater.inflate(R.menu.playlist_page_menu, menu);
|
||||||
initMenuOption(menu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -103,7 +102,7 @@ public class PlaylistPageFragment extends Fragment implements ClickCallback {
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||||
if (item.getItemId() == R.id.action_download_playlist) {
|
if (item.getItemId() == R.id.action_download_playlist) {
|
||||||
playlistPageViewModel.getPlaylistSongLiveList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> {
|
playlistPageViewModel.getPlaylistSongLiveList().observe(getViewLifecycleOwner(), songs -> {
|
||||||
if (isVisible() && getActivity() != null) {
|
if (isVisible() && getActivity() != null) {
|
||||||
DownloadUtil.getDownloadTracker(requireContext()).download(
|
DownloadUtil.getDownloadTracker(requireContext()).download(
|
||||||
MappingUtil.mapMediaItems(songs, false),
|
MappingUtil.mapMediaItems(songs, false),
|
||||||
|
|
@ -117,12 +116,6 @@ public class PlaylistPageFragment extends Fragment implements ClickCallback {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == R.id.action_pin_playlist) {
|
|
||||||
playlistPageViewModel.setPinned(true);
|
|
||||||
return true;
|
|
||||||
} else if (item.getItemId() == R.id.action_unpin_playlist) {
|
|
||||||
playlistPageViewModel.setPinned(false);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -130,14 +123,6 @@ public class PlaylistPageFragment extends Fragment implements ClickCallback {
|
||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
playlistPageViewModel.setPlaylist(requireArguments().getParcelable(Constants.PLAYLIST_OBJECT));
|
playlistPageViewModel.setPlaylist(requireArguments().getParcelable(Constants.PLAYLIST_OBJECT));
|
||||||
playlistPageViewModel.setOffline(requireArguments().getBoolean("is_offline"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initMenuOption(Menu menu) {
|
|
||||||
playlistPageViewModel.isPinned(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), isPinned -> {
|
|
||||||
menu.findItem(R.id.action_unpin_playlist).setVisible(isPinned);
|
|
||||||
menu.findItem(R.id.action_pin_playlist).setVisible(!isPinned);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initAppBar() {
|
private void initAppBar() {
|
||||||
|
|
@ -154,18 +139,13 @@ public class PlaylistPageFragment extends Fragment implements ClickCallback {
|
||||||
bind.playlistSongCountLabel.setText(getString(R.string.playlist_song_count, playlistPageViewModel.getPlaylist().getSongCount()));
|
bind.playlistSongCountLabel.setText(getString(R.string.playlist_song_count, playlistPageViewModel.getPlaylist().getSongCount()));
|
||||||
bind.playlistDurationLabel.setText(getString(R.string.playlist_duration, MusicUtil.getReadableDurationString(playlistPageViewModel.getPlaylist().getDuration(), false)));
|
bind.playlistDurationLabel.setText(getString(R.string.playlist_duration, MusicUtil.getReadableDurationString(playlistPageViewModel.getPlaylist().getDuration(), false)));
|
||||||
|
|
||||||
if (playlistPageViewModel.isOffline()) {
|
|
||||||
bind.playlistSongCountLabel.setVisibility(View.GONE);
|
|
||||||
bind.playlistDurationLabel.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
bind.animToolbar.setNavigationOnClickListener(v -> activity.navController.navigateUp());
|
bind.animToolbar.setNavigationOnClickListener(v -> activity.navController.navigateUp());
|
||||||
|
|
||||||
Objects.requireNonNull(bind.animToolbar.getOverflowIcon()).setTint(requireContext().getResources().getColor(R.color.titleTextColor, null));
|
Objects.requireNonNull(bind.animToolbar.getOverflowIcon()).setTint(requireContext().getResources().getColor(R.color.titleTextColor, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initMusicButton() {
|
private void initMusicButton() {
|
||||||
playlistPageViewModel.getPlaylistSongLiveList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> {
|
playlistPageViewModel.getPlaylistSongLiveList().observe(getViewLifecycleOwner(), songs -> {
|
||||||
if (bind != null) {
|
if (bind != null) {
|
||||||
bind.playlistPagePlayButton.setOnClickListener(v -> {
|
bind.playlistPagePlayButton.setOnClickListener(v -> {
|
||||||
MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), songs, 0);
|
MediaManager.startQueue(mediaBrowserListenableFuture, requireContext(), songs, 0);
|
||||||
|
|
@ -182,39 +162,11 @@ public class PlaylistPageFragment extends Fragment implements ClickCallback {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initBackCover() {
|
private void initBackCover() {
|
||||||
playlistPageViewModel.getPlaylistSongLiveList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> {
|
CustomGlideRequest.Builder
|
||||||
if (bind != null) {
|
.from(requireContext(), playlistPageViewModel.getPlaylist().getCoverArtId(), CustomGlideRequest.PLAYLIST_PIC, null)
|
||||||
Collections.shuffle(songs);
|
.build()
|
||||||
|
.transform(new CenterCrop(), new GranularRoundedCorners(CustomGlideRequest.CORNER_RADIUS, 0, 0, 0))
|
||||||
// Pic top-left
|
.into(bind.playlistCoverImageView);
|
||||||
CustomGlideRequest.Builder
|
|
||||||
.from(requireContext(), songs.size() > 0 ? songs.get(0).getCoverArtId() : playlistPageViewModel.getPlaylist().getCoverArtId(), CustomGlideRequest.PLAYLIST_PIC, null)
|
|
||||||
.build()
|
|
||||||
.transform(new CenterCrop(), new GranularRoundedCorners(CustomGlideRequest.CORNER_RADIUS, 0, 0, 0))
|
|
||||||
.into(bind.playlistCoverImageViewTopLeft);
|
|
||||||
|
|
||||||
// Pic top-right
|
|
||||||
CustomGlideRequest.Builder
|
|
||||||
.from(requireContext(), songs.size() > 1 ? songs.get(1).getCoverArtId() : playlistPageViewModel.getPlaylist().getCoverArtId(), CustomGlideRequest.PLAYLIST_PIC, null)
|
|
||||||
.build()
|
|
||||||
.transform(new CenterCrop(), new GranularRoundedCorners(0, CustomGlideRequest.CORNER_RADIUS, 0, 0))
|
|
||||||
.into(bind.playlistCoverImageViewTopRight);
|
|
||||||
|
|
||||||
// Pic bottom-left
|
|
||||||
CustomGlideRequest.Builder
|
|
||||||
.from(requireContext(), songs.size() > 2 ? songs.get(2).getCoverArtId() : playlistPageViewModel.getPlaylist().getCoverArtId(), CustomGlideRequest.PLAYLIST_PIC, null)
|
|
||||||
.build()
|
|
||||||
.transform(new CenterCrop(), new GranularRoundedCorners(0, 0, 0, CustomGlideRequest.CORNER_RADIUS))
|
|
||||||
.into(bind.playlistCoverImageViewBottomLeft);
|
|
||||||
|
|
||||||
// Pic bottom-right
|
|
||||||
CustomGlideRequest.Builder
|
|
||||||
.from(requireContext(), songs.size() > 3 ? songs.get(3).getCoverArtId() : playlistPageViewModel.getPlaylist().getCoverArtId(), CustomGlideRequest.PLAYLIST_PIC, null)
|
|
||||||
.build()
|
|
||||||
.transform(new CenterCrop(), new GranularRoundedCorners(0, 0, CustomGlideRequest.CORNER_RADIUS, 0))
|
|
||||||
.into(bind.playlistCoverImageViewBottomRight);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initSongsView() {
|
private void initSongsView() {
|
||||||
|
|
@ -224,7 +176,7 @@ public class PlaylistPageFragment extends Fragment implements ClickCallback {
|
||||||
songHorizontalAdapter = new SongHorizontalAdapter(this, true);
|
songHorizontalAdapter = new SongHorizontalAdapter(this, true);
|
||||||
bind.songRecyclerView.setAdapter(songHorizontalAdapter);
|
bind.songRecyclerView.setAdapter(songHorizontalAdapter);
|
||||||
|
|
||||||
playlistPageViewModel.getPlaylistSongLiveList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> songHorizontalAdapter.setItems(songs));
|
playlistPageViewModel.getPlaylistSongLiveList().observe(getViewLifecycleOwner(), songs -> songHorizontalAdapter.setItems(songs));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeMediaBrowser() {
|
private void initializeMediaBrowser() {
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ public class SongListPageFragment extends Fragment implements ClickCallback {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initButtons() {
|
private void initButtons() {
|
||||||
songListPageViewModel.getSongList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> {
|
songListPageViewModel.getSongList().observe(getViewLifecycleOwner(), songs -> {
|
||||||
if (bind != null) {
|
if (bind != null) {
|
||||||
bind.songListShuffleImageView.setOnClickListener(v -> {
|
bind.songListShuffleImageView.setOnClickListener(v -> {
|
||||||
Collections.shuffle(songs);
|
Collections.shuffle(songs);
|
||||||
|
|
@ -163,7 +163,7 @@ public class SongListPageFragment extends Fragment implements ClickCallback {
|
||||||
|
|
||||||
songHorizontalAdapter = new SongHorizontalAdapter(this, true);
|
songHorizontalAdapter = new SongHorizontalAdapter(this, true);
|
||||||
bind.songListRecyclerView.setAdapter(songHorizontalAdapter);
|
bind.songListRecyclerView.setAdapter(songHorizontalAdapter);
|
||||||
songListPageViewModel.getSongList(getViewLifecycleOwner()).observe(getViewLifecycleOwner(), songs -> songHorizontalAdapter.setItems(songs));
|
songListPageViewModel.getSongList().observe(getViewLifecycleOwner(), songs -> songHorizontalAdapter.setItems(songs));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeMediaBrowser() {
|
private void initializeMediaBrowser() {
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import com.cappielloantonio.play.glide.CustomGlideRequest;
|
||||||
import com.cappielloantonio.play.service.MediaService;
|
import com.cappielloantonio.play.service.MediaService;
|
||||||
import com.cappielloantonio.play.subsonic.models.PodcastEpisode;
|
import com.cappielloantonio.play.subsonic.models.PodcastEpisode;
|
||||||
import com.cappielloantonio.play.ui.activity.MainActivity;
|
import com.cappielloantonio.play.ui.activity.MainActivity;
|
||||||
|
import com.cappielloantonio.play.util.Constants;
|
||||||
import com.cappielloantonio.play.util.MusicUtil;
|
import com.cappielloantonio.play.util.MusicUtil;
|
||||||
import com.cappielloantonio.play.viewmodel.PodcastBottomSheetViewModel;
|
import com.cappielloantonio.play.viewmodel.PodcastBottomSheetViewModel;
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||||
|
|
@ -39,7 +40,7 @@ public class PodcastBottomSheetDialog extends BottomSheetDialogFragment implemen
|
||||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.bottom_sheet_podcast_dialog, container, false);
|
View view = inflater.inflate(R.layout.bottom_sheet_podcast_dialog, container, false);
|
||||||
|
|
||||||
podcast = requireArguments().getParcelable("podcast_object");
|
podcast = requireArguments().getParcelable(Constants.PODCAST_OBJECT);
|
||||||
|
|
||||||
podcastBottomSheetViewModel = new ViewModelProvider(requireActivity()).get(PodcastBottomSheetViewModel.class);
|
podcastBottomSheetViewModel = new ViewModelProvider(requireActivity()).get(PodcastBottomSheetViewModel.class);
|
||||||
podcastBottomSheetViewModel.setPodcast(podcast);
|
podcastBottomSheetViewModel.setPodcast(podcast);
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,12 @@ object Constants {
|
||||||
|
|
||||||
const val TRACK_OBJECT = "TRACK_OBJECT"
|
const val TRACK_OBJECT = "TRACK_OBJECT"
|
||||||
const val TRACKS_OBJECT = "TRACKS_OBJECT"
|
const val TRACKS_OBJECT = "TRACKS_OBJECT"
|
||||||
|
|
||||||
const val ALBUM_OBJECT = "ALBUM_OBJECT"
|
const val ALBUM_OBJECT = "ALBUM_OBJECT"
|
||||||
|
const val ARTIST_OBJECT = "ARTIST_OBJECT"
|
||||||
|
const val GENRE_OBJECT = "GENRE_OBJECT"
|
||||||
|
const val PLAYLIST_OBJECT = "PLAYLIST_OBJECT"
|
||||||
|
const val PODCAST_OBJECT = "PODCAST_OBJECT"
|
||||||
|
|
||||||
const val ALBUM_RECENTLY_PLAYED = "ALBUM_RECENTLY_PLAYED"
|
const val ALBUM_RECENTLY_PLAYED = "ALBUM_RECENTLY_PLAYED"
|
||||||
const val ALBUM_MOST_PLAYED = "ALBUM_MOST_PLAYED"
|
const val ALBUM_MOST_PLAYED = "ALBUM_MOST_PLAYED"
|
||||||
const val ALBUM_RECENTLY_ADDED = "ALBUM_RECENTLY_ADDED"
|
const val ALBUM_RECENTLY_ADDED = "ALBUM_RECENTLY_ADDED"
|
||||||
|
|
@ -21,17 +25,14 @@ object Constants {
|
||||||
const val ALBUM_ORDER_BY_YEAR = "ALBUM_ORDER_BY_YEAR"
|
const val ALBUM_ORDER_BY_YEAR = "ALBUM_ORDER_BY_YEAR"
|
||||||
const val ALBUM_ORDER_BY_RANDOM = "ALBUM_ORDER_BY_RANDOM"
|
const val ALBUM_ORDER_BY_RANDOM = "ALBUM_ORDER_BY_RANDOM"
|
||||||
|
|
||||||
const val ARTIST_OBJECT = "ARTIST_OBJECT"
|
|
||||||
const val ARTIST_DOWNLOADED = "ARTIST_DOWNLOADED"
|
const val ARTIST_DOWNLOADED = "ARTIST_DOWNLOADED"
|
||||||
const val ARTIST_STARRED = "ARTIST_STARRED"
|
const val ARTIST_STARRED = "ARTIST_STARRED"
|
||||||
const val ARTIST_ORDER_BY_NAME = "ARTIST_ORDER_BY_NAME"
|
const val ARTIST_ORDER_BY_NAME = "ARTIST_ORDER_BY_NAME"
|
||||||
const val ARTIST_ORDER_BY_RANDOM = "ARTIST_ORDER_BY_RANDOM"
|
const val ARTIST_ORDER_BY_RANDOM = "ARTIST_ORDER_BY_RANDOM"
|
||||||
|
|
||||||
const val GENRE_OBJECT = "GENRE_OBJECT"
|
|
||||||
const val GENRE_ORDER_BY_NAME = "GENRE_ORDER_BY_NAME"
|
const val GENRE_ORDER_BY_NAME = "GENRE_ORDER_BY_NAME"
|
||||||
const val GENRE_ORDER_BY_RANDOM = "GENRE_ORDER_BY_RANDOM"
|
const val GENRE_ORDER_BY_RANDOM = "GENRE_ORDER_BY_RANDOM"
|
||||||
|
|
||||||
const val PLAYLIST_OBJECT = "PLAYLIST_OBJECT"
|
|
||||||
const val PLAYLIST_ALL = "ALL"
|
const val PLAYLIST_ALL = "ALL"
|
||||||
const val PLAYLIST_DOWNLOADED = "DOWNLOADED"
|
const val PLAYLIST_DOWNLOADED = "DOWNLOADED"
|
||||||
const val PLAYLIST_ORDER_BY_NAME = "ORDER_BY_NAME"
|
const val PLAYLIST_ORDER_BY_NAME = "ORDER_BY_NAME"
|
||||||
|
|
@ -59,4 +60,7 @@ object Constants {
|
||||||
const val MEDIA_STARRED = "MEDIA_STARRED"
|
const val MEDIA_STARRED = "MEDIA_STARRED"
|
||||||
const val MEDIA_DOWNLOADED = "MEDIA_DOWNLOADED"
|
const val MEDIA_DOWNLOADED = "MEDIA_DOWNLOADED"
|
||||||
const val MEDIA_FROM_ALBUM = "MEDIA_FROM_ALBUM"
|
const val MEDIA_FROM_ALBUM = "MEDIA_FROM_ALBUM"
|
||||||
|
const val MEDIA_MIX = "MEDIA_MIX"
|
||||||
|
const val MEDIA_CHRONOLOGY = "MEDIA_CHRONOLOGY"
|
||||||
|
const val MEDIA_BEST_OF = "MEDIA_BEST_OF"
|
||||||
}
|
}
|
||||||
|
|
@ -12,13 +12,11 @@ import com.cappielloantonio.play.model.Chronology;
|
||||||
import com.cappielloantonio.play.repository.AlbumRepository;
|
import com.cappielloantonio.play.repository.AlbumRepository;
|
||||||
import com.cappielloantonio.play.repository.ArtistRepository;
|
import com.cappielloantonio.play.repository.ArtistRepository;
|
||||||
import com.cappielloantonio.play.repository.ChronologyRepository;
|
import com.cappielloantonio.play.repository.ChronologyRepository;
|
||||||
import com.cappielloantonio.play.repository.PlaylistRepository;
|
|
||||||
import com.cappielloantonio.play.repository.PodcastRepository;
|
import com.cappielloantonio.play.repository.PodcastRepository;
|
||||||
import com.cappielloantonio.play.repository.SongRepository;
|
import com.cappielloantonio.play.repository.SongRepository;
|
||||||
import com.cappielloantonio.play.subsonic.models.AlbumID3;
|
import com.cappielloantonio.play.subsonic.models.AlbumID3;
|
||||||
import com.cappielloantonio.play.subsonic.models.ArtistID3;
|
import com.cappielloantonio.play.subsonic.models.ArtistID3;
|
||||||
import com.cappielloantonio.play.subsonic.models.Child;
|
import com.cappielloantonio.play.subsonic.models.Child;
|
||||||
import com.cappielloantonio.play.subsonic.models.Playlist;
|
|
||||||
import com.cappielloantonio.play.subsonic.models.PodcastEpisode;
|
import com.cappielloantonio.play.subsonic.models.PodcastEpisode;
|
||||||
import com.cappielloantonio.play.util.Preferences;
|
import com.cappielloantonio.play.util.Preferences;
|
||||||
|
|
||||||
|
|
@ -33,7 +31,6 @@ public class HomeViewModel extends AndroidViewModel {
|
||||||
private final SongRepository songRepository;
|
private final SongRepository songRepository;
|
||||||
private final AlbumRepository albumRepository;
|
private final AlbumRepository albumRepository;
|
||||||
private final ArtistRepository artistRepository;
|
private final ArtistRepository artistRepository;
|
||||||
private final PlaylistRepository playlistRepository;
|
|
||||||
private final PodcastRepository podcastRepository;
|
private final PodcastRepository podcastRepository;
|
||||||
private final ChronologyRepository chronologyRepository;
|
private final ChronologyRepository chronologyRepository;
|
||||||
|
|
||||||
|
|
@ -49,7 +46,6 @@ public class HomeViewModel extends AndroidViewModel {
|
||||||
private final MutableLiveData<List<AlbumID3>> recentlyPlayedAlbumSample = new MutableLiveData<>(null);
|
private final MutableLiveData<List<AlbumID3>> recentlyPlayedAlbumSample = new MutableLiveData<>(null);
|
||||||
private final MutableLiveData<List<Integer>> years = new MutableLiveData<>(null);
|
private final MutableLiveData<List<Integer>> years = new MutableLiveData<>(null);
|
||||||
private final MutableLiveData<List<AlbumID3>> recentlyAddedAlbumSample = new MutableLiveData<>(null);
|
private final MutableLiveData<List<AlbumID3>> recentlyAddedAlbumSample = new MutableLiveData<>(null);
|
||||||
private final MutableLiveData<List<Playlist>> pinnedPlaylists = new MutableLiveData<>(null);
|
|
||||||
private final MutableLiveData<List<PodcastEpisode>> newestPodcastEpisodes = new MutableLiveData<>(null);
|
private final MutableLiveData<List<PodcastEpisode>> newestPodcastEpisodes = new MutableLiveData<>(null);
|
||||||
|
|
||||||
private final MutableLiveData<List<Chronology>> thisGridTopSong = new MutableLiveData<>(null);
|
private final MutableLiveData<List<Chronology>> thisGridTopSong = new MutableLiveData<>(null);
|
||||||
|
|
@ -63,7 +59,6 @@ public class HomeViewModel extends AndroidViewModel {
|
||||||
songRepository = new SongRepository();
|
songRepository = new SongRepository();
|
||||||
albumRepository = new AlbumRepository();
|
albumRepository = new AlbumRepository();
|
||||||
artistRepository = new ArtistRepository();
|
artistRepository = new ArtistRepository();
|
||||||
playlistRepository = new PlaylistRepository();
|
|
||||||
podcastRepository = new PodcastRepository();
|
podcastRepository = new PodcastRepository();
|
||||||
chronologyRepository = new ChronologyRepository();
|
chronologyRepository = new ChronologyRepository();
|
||||||
}
|
}
|
||||||
|
|
@ -185,20 +180,6 @@ public class HomeViewModel extends AndroidViewModel {
|
||||||
return recentlyPlayedAlbumSample;
|
return recentlyPlayedAlbumSample;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<Playlist>> getPinnedPlaylistList(LifecycleOwner owner, int maxNumber, boolean random) {
|
|
||||||
playlistRepository.getPinnedPlaylists(Preferences.getServerId()).observe(owner, playlists -> {
|
|
||||||
if (random) Collections.shuffle(playlists);
|
|
||||||
List<Playlist> subPlaylist = playlists.subList(0, Math.min(maxNumber, playlists.size()));
|
|
||||||
pinnedPlaylists.postValue(subPlaylist);
|
|
||||||
});
|
|
||||||
|
|
||||||
return pinnedPlaylists;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiveData<List<Child>> getPlaylistSongLiveList(String playlistId) {
|
|
||||||
return playlistRepository.getPlaylistSongs(playlistId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiveData<List<PodcastEpisode>> getNewestPodcastEpisodes(LifecycleOwner owner) {
|
public LiveData<List<PodcastEpisode>> getNewestPodcastEpisodes(LifecycleOwner owner) {
|
||||||
if (newestPodcastEpisodes.getValue() == null) {
|
if (newestPodcastEpisodes.getValue() == null) {
|
||||||
podcastRepository.getNewestPodcastEpisodes(20).observe(owner, newestPodcastEpisodes::postValue);
|
podcastRepository.getNewestPodcastEpisodes(20).observe(owner, newestPodcastEpisodes::postValue);
|
||||||
|
|
@ -215,12 +196,20 @@ public class HomeViewModel extends AndroidViewModel {
|
||||||
return mediaInstantMix;
|
return mediaInstantMix;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<Child>> getArtistInstantMix(ArtistID3 artist) {
|
public LiveData<List<Child>> getArtistInstantMix(LifecycleOwner owner, ArtistID3 artist) {
|
||||||
return artistRepository.getInstantMix(artist, 20);
|
if (artistInstantMix.getValue() == null) {
|
||||||
|
artistRepository.getTopSongs(artist.getName(), 10).observe(owner, artistInstantMix::postValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return artistInstantMix;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<Child>> getArtistBestOf(ArtistID3 artist) {
|
public LiveData<List<Child>> getArtistBestOf(LifecycleOwner owner, ArtistID3 artist) {
|
||||||
return artistRepository.getTopSongs(artist.getName(), 10);
|
if (bestOfArtists.getValue() == null) {
|
||||||
|
artistRepository.getTopSongs(artist.getName(), 10).observe(owner, artistBestOf::postValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return artistBestOf;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshDiscoverySongSample(LifecycleOwner owner) {
|
public void refreshDiscoverySongSample(LifecycleOwner owner) {
|
||||||
|
|
|
||||||
|
|
@ -8,63 +8,32 @@ import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
import com.cappielloantonio.play.repository.DownloadRepository;
|
|
||||||
import com.cappielloantonio.play.repository.PlaylistRepository;
|
import com.cappielloantonio.play.repository.PlaylistRepository;
|
||||||
import com.cappielloantonio.play.subsonic.models.Playlist;
|
import com.cappielloantonio.play.subsonic.models.Playlist;
|
||||||
import com.cappielloantonio.play.util.Constants;
|
|
||||||
import com.cappielloantonio.play.util.Preferences;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class PlaylistCatalogueViewModel extends AndroidViewModel {
|
public class PlaylistCatalogueViewModel extends AndroidViewModel {
|
||||||
private final PlaylistRepository playlistRepository;
|
private final PlaylistRepository playlistRepository;
|
||||||
private final DownloadRepository downloadRepository;
|
|
||||||
|
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
private MutableLiveData<List<Playlist>> playlistList;
|
private final MutableLiveData<List<Playlist>> playlistList = new MutableLiveData<>(null);
|
||||||
private MutableLiveData<List<Playlist>> pinnedPlaylistList;
|
|
||||||
|
|
||||||
public PlaylistCatalogueViewModel(@NonNull Application application) {
|
public PlaylistCatalogueViewModel(@NonNull Application application) {
|
||||||
super(application);
|
super(application);
|
||||||
|
|
||||||
playlistRepository = new PlaylistRepository();
|
playlistRepository = new PlaylistRepository();
|
||||||
downloadRepository = new DownloadRepository();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<Playlist>> getPlaylistList(LifecycleOwner owner) {
|
public LiveData<List<Playlist>> getPlaylistList(LifecycleOwner owner) {
|
||||||
playlistList = new MutableLiveData<>(new ArrayList<>());
|
if (playlistList.getValue() == null) {
|
||||||
|
playlistRepository.getPlaylists(false, -1).observe(owner, playlistList::postValue);
|
||||||
switch (type) {
|
|
||||||
case Constants.PLAYLIST_ALL:
|
|
||||||
playlistRepository.getPlaylists(false, -1).observe(owner, playlists -> playlistList.postValue(playlists));
|
|
||||||
break;
|
|
||||||
case Constants.PLAYLIST_DOWNLOADED:
|
|
||||||
// TODO
|
|
||||||
//downloadRepository.getLivePlaylist().observe(owner, downloads -> playlistList.setValue(MappingUtil.mapDownloadToPlaylist(downloads)));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
playlistRepository.getPlaylists(false, -1);
|
|
||||||
|
|
||||||
return playlistList;
|
return playlistList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<Playlist>> getPinnedPlaylistList(LifecycleOwner owner) {
|
|
||||||
pinnedPlaylistList = new MutableLiveData<>(new ArrayList<>());
|
|
||||||
playlistRepository.getPinnedPlaylists(Preferences.getServerId()).observe(owner, playlists -> pinnedPlaylistList.postValue(playlists));
|
|
||||||
return pinnedPlaylistList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unpinPlaylist(List<Playlist> playlists) {
|
|
||||||
if (type.equals(Constants.PLAYLIST_ALL)) {
|
|
||||||
for (Playlist playlist : playlists) {
|
|
||||||
playlistRepository.delete(playlist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setType(String type) {
|
public void setType(String type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,23 +4,16 @@ import android.app.Application;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.lifecycle.AndroidViewModel;
|
import androidx.lifecycle.AndroidViewModel;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.MutableLiveData;
|
|
||||||
|
|
||||||
import com.cappielloantonio.play.repository.DownloadRepository;
|
|
||||||
import com.cappielloantonio.play.repository.PlaylistRepository;
|
import com.cappielloantonio.play.repository.PlaylistRepository;
|
||||||
import com.cappielloantonio.play.subsonic.models.Child;
|
import com.cappielloantonio.play.subsonic.models.Child;
|
||||||
import com.cappielloantonio.play.subsonic.models.Playlist;
|
import com.cappielloantonio.play.subsonic.models.Playlist;
|
||||||
import com.cappielloantonio.play.util.Preferences;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class PlaylistPageViewModel extends AndroidViewModel {
|
public class PlaylistPageViewModel extends AndroidViewModel {
|
||||||
private final PlaylistRepository playlistRepository;
|
private final PlaylistRepository playlistRepository;
|
||||||
private final DownloadRepository downloadRepository;
|
|
||||||
|
|
||||||
private MutableLiveData<List<Child>> playlistSongLiveList = new MutableLiveData<>();
|
|
||||||
|
|
||||||
private Playlist playlist;
|
private Playlist playlist;
|
||||||
private boolean isOffline;
|
private boolean isOffline;
|
||||||
|
|
@ -29,18 +22,10 @@ public class PlaylistPageViewModel extends AndroidViewModel {
|
||||||
super(application);
|
super(application);
|
||||||
|
|
||||||
playlistRepository = new PlaylistRepository();
|
playlistRepository = new PlaylistRepository();
|
||||||
downloadRepository = new DownloadRepository();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<Child>> getPlaylistSongLiveList(LifecycleOwner owner) {
|
public LiveData<List<Child>> getPlaylistSongLiveList() {
|
||||||
if (isOffline) {
|
return playlistRepository.getPlaylistSongs(playlist.getId());
|
||||||
// TODO
|
|
||||||
// downloadRepository.getLiveDownloadFromPlaylist(playlist.getId()).observe(owner, downloads -> playlistSongLiveList.postValue(MappingUtil.mapDownloadToMedia(downloads)));
|
|
||||||
} else {
|
|
||||||
playlistSongLiveList = playlistRepository.getPlaylistSongs(playlist.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
return playlistSongLiveList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Playlist getPlaylist() {
|
public Playlist getPlaylist() {
|
||||||
|
|
@ -49,29 +34,5 @@ public class PlaylistPageViewModel extends AndroidViewModel {
|
||||||
|
|
||||||
public void setPlaylist(Playlist playlist) {
|
public void setPlaylist(Playlist playlist) {
|
||||||
this.playlist = playlist;
|
this.playlist = playlist;
|
||||||
// TODO
|
|
||||||
// this.playlist.setServer(Preferences.getServerId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOffline(boolean offline) {
|
|
||||||
isOffline = offline;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isOffline() {
|
|
||||||
return isOffline;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiveData<Boolean> isPinned(LifecycleOwner owner) {
|
|
||||||
MutableLiveData<Boolean> isPinnedLive = new MutableLiveData<>();
|
|
||||||
playlistRepository.getPinnedPlaylists(Preferences.getServerId()).observe(owner, playlists -> isPinnedLive.postValue(playlists.contains(playlist)));
|
|
||||||
return isPinnedLive;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPinned(boolean isNowPinned) {
|
|
||||||
if (isNowPinned) {
|
|
||||||
playlistRepository.insert(playlist);
|
|
||||||
} else {
|
|
||||||
playlistRepository.delete(playlist);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,10 @@ import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.lifecycle.AndroidViewModel;
|
import androidx.lifecycle.AndroidViewModel;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
import com.cappielloantonio.play.repository.ArtistRepository;
|
import com.cappielloantonio.play.repository.ArtistRepository;
|
||||||
import com.cappielloantonio.play.repository.DownloadRepository;
|
|
||||||
import com.cappielloantonio.play.repository.SongRepository;
|
import com.cappielloantonio.play.repository.SongRepository;
|
||||||
import com.cappielloantonio.play.subsonic.models.AlbumID3;
|
import com.cappielloantonio.play.subsonic.models.AlbumID3;
|
||||||
import com.cappielloantonio.play.subsonic.models.ArtistID3;
|
import com.cappielloantonio.play.subsonic.models.ArtistID3;
|
||||||
|
|
@ -24,7 +22,6 @@ import java.util.List;
|
||||||
public class SongListPageViewModel extends AndroidViewModel {
|
public class SongListPageViewModel extends AndroidViewModel {
|
||||||
private final SongRepository songRepository;
|
private final SongRepository songRepository;
|
||||||
private final ArtistRepository artistRepository;
|
private final ArtistRepository artistRepository;
|
||||||
private final DownloadRepository downloadRepository;
|
|
||||||
|
|
||||||
public String title;
|
public String title;
|
||||||
public String toolbarTitle;
|
public String toolbarTitle;
|
||||||
|
|
@ -44,10 +41,9 @@ public class SongListPageViewModel extends AndroidViewModel {
|
||||||
|
|
||||||
songRepository = new SongRepository();
|
songRepository = new SongRepository();
|
||||||
artistRepository = new ArtistRepository();
|
artistRepository = new ArtistRepository();
|
||||||
downloadRepository = new DownloadRepository();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<List<Child>> getSongList(LifecycleOwner owner) {
|
public LiveData<List<Child>> getSongList() {
|
||||||
songList = new MutableLiveData<>(new ArrayList<>());
|
songList = new MutableLiveData<>(new ArrayList<>());
|
||||||
|
|
||||||
switch (title) {
|
switch (title) {
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@
|
||||||
android:paddingStart="16dp"
|
android:paddingStart="16dp"
|
||||||
android:paddingTop="8dp"
|
android:paddingTop="8dp"
|
||||||
android:paddingEnd="16dp"
|
android:paddingEnd="16dp"
|
||||||
android:text="@string/download_title_tracks_section" />
|
android:text="@string/download_title_section" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/downloaded_tracks_recycler_view"
|
android:id="@+id/downloaded_tracks_recycler_view"
|
||||||
|
|
|
||||||
|
|
@ -30,48 +30,16 @@
|
||||||
android:paddingTop="8dp">
|
android:paddingTop="8dp">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/playlist_cover_image_view_top_left"
|
android:id="@+id/playlist_cover_image_view"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_marginStart="64dp"
|
android:layout_marginStart="64dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
app:layout_constraintDimensionRatio="H,1:1"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/playlist_cover_image_view_top_right"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/playlist_cover_image_view_top_right"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginEnd="64dp"
|
android:layout_marginEnd="64dp"
|
||||||
app:layout_constraintDimensionRatio="H,1:1"
|
app:layout_constraintDimensionRatio="H,1:1"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/playlist_cover_image_view_top_left"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/playlist_cover_image_view_bottom_left"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginStart="64dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
app:layout_constraintDimensionRatio="H,1:1"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/playlist_cover_image_view_bottom_right"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/playlist_cover_image_view_top_left" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/playlist_cover_image_view_bottom_right"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_marginEnd="64dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
app:layout_constraintDimensionRatio="H,1:1"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/playlist_cover_image_view_bottom_left"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/playlist_cover_image_view_bottom_left" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/playlist_name_label"
|
android:id="@+id/playlist_name_label"
|
||||||
|
|
@ -87,7 +55,7 @@
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/playlist_cover_image_view_bottom_left" />
|
app:layout_constraintTop_toBottomOf="@+id/playlist_cover_image_view" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/playlist_song_count_label"
|
android:id="@+id/playlist_song_count_label"
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,4 @@
|
||||||
android:icon="@drawable/ic_file_download"
|
android:icon="@drawable/ic_file_download"
|
||||||
android:title="@string/menu_download_all_button"
|
android:title="@string/menu_download_all_button"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
<item
|
|
||||||
android:id="@+id/action_pin_playlist"
|
|
||||||
android:icon="@drawable/ic_pin_in"
|
|
||||||
android:title="@string/menu_pin_button"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_unpin_playlist"
|
|
||||||
android:icon="@drawable/ic_pin_out"
|
|
||||||
android:title="@string/menu_unpin_button"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
</menu>
|
</menu>
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<dimen name="appbar_header_height">296dp</dimen>
|
<dimen name="appbar_header_height">296dp</dimen>
|
||||||
<dimen name="activity_margin_content">24dp</dimen>
|
<dimen name="activity_margin_content">24dp</dimen>
|
||||||
<dimen name="bottom_sheet_peek_height">56dp</dimen>
|
<dimen name="bottom_sheet_peek_height">56dp</dimen>
|
||||||
<dimen name="global_padding_bottom">64dp</dimen>
|
<dimen name="global_padding_bottom">128dp</dimen>
|
||||||
<dimen name="radius">2dp</dimen>
|
<dimen name="radius">2dp</dimen>
|
||||||
<dimen name="dots_height">2dp</dimen>
|
<dimen name="dots_height">2dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
<string name="download_title_artist_see_all_button">See all</string>
|
<string name="download_title_artist_see_all_button">See all</string>
|
||||||
<string name="download_title_playlist_section">Playlists</string>
|
<string name="download_title_playlist_section">Playlists</string>
|
||||||
<string name="download_title_playlist_see_all_button">See all</string>
|
<string name="download_title_playlist_see_all_button">See all</string>
|
||||||
<string name="download_title_tracks_section">Tracks</string>
|
<string name="download_title_section">Downloads</string>
|
||||||
<string name="download_title_tracks_see_all_button">See all</string>
|
<string name="download_title_tracks_see_all_button">See all</string>
|
||||||
<string name="empty_string" />
|
<string name="empty_string" />
|
||||||
<string name="error_required">Required</string>
|
<string name="error_required">Required</string>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue