From 930f7e8aa3686fb1bb5f0a4487875a2613cbc155 Mon Sep 17 00:00:00 2001 From: dkanada Date: Thu, 30 Apr 2020 23:13:53 +0900 Subject: [PATCH] work on item deletion from playlists --- .../song/OrderablePlaylistSongAdapter.java | 5 +- .../dialogs/AddToPlaylistDialog.java | 35 ++++++++----- .../dialogs/CreatePlaylistDialog.java | 5 +- .../dialogs/RemoveFromPlaylistDialog.java | 9 +++- .../gramophone/model/PlaylistSong.java | 42 ++++++++++++++++ .../ui/activities/PlaylistDetailActivity.java | 6 +-- .../gramophone/util/PlaylistUtil.java | 49 ++++++++++++++++++- .../kabouzeid/gramophone/util/QueryUtil.java | 2 + 8 files changed, 131 insertions(+), 22 deletions(-) create mode 100644 app/src/main/java/com/kabouzeid/gramophone/model/PlaylistSong.java diff --git a/app/src/main/java/com/kabouzeid/gramophone/adapter/song/OrderablePlaylistSongAdapter.java b/app/src/main/java/com/kabouzeid/gramophone/adapter/song/OrderablePlaylistSongAdapter.java index b7aa89de..131eb1a0 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/adapter/song/OrderablePlaylistSongAdapter.java +++ b/app/src/main/java/com/kabouzeid/gramophone/adapter/song/OrderablePlaylistSongAdapter.java @@ -19,13 +19,12 @@ import com.kabouzeid.gramophone.util.ViewUtil; import java.util.List; -@SuppressWarnings("unchecked") public class OrderablePlaylistSongAdapter extends PlaylistSongAdapter implements DraggableItemAdapter { private OnMoveItemListener onMoveItemListener; public OrderablePlaylistSongAdapter(@NonNull AppCompatActivity activity, @NonNull List dataSet, @LayoutRes int itemLayoutRes, boolean usePalette, @Nullable CabHolder cabHolder, @Nullable OnMoveItemListener onMoveItemListener) { - super(activity, (List) dataSet, itemLayoutRes, usePalette, cabHolder); + super(activity, dataSet, itemLayoutRes, usePalette, cabHolder); setMultiSelectMenuRes(R.menu.menu_playlists_songs_selection); this.onMoveItemListener = onMoveItemListener; } @@ -47,7 +46,7 @@ public class OrderablePlaylistSongAdapter extends PlaylistSongAdapter implements protected void onMultipleItemAction(@NonNull MenuItem menuItem, @NonNull List selection) { switch (menuItem.getItemId()) { case R.id.action_remove_from_playlist: - RemoveFromPlaylistDialog.create((List) (List) selection).show(activity.getSupportFragmentManager(), "ADD_PLAYLIST"); + RemoveFromPlaylistDialog.create(selection).show(activity.getSupportFragmentManager(), "ADD_PLAYLIST"); return; } diff --git a/app/src/main/java/com/kabouzeid/gramophone/dialogs/AddToPlaylistDialog.java b/app/src/main/java/com/kabouzeid/gramophone/dialogs/AddToPlaylistDialog.java index 74dfba8f..7e51a70f 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/dialogs/AddToPlaylistDialog.java +++ b/app/src/main/java/com/kabouzeid/gramophone/dialogs/AddToPlaylistDialog.java @@ -7,9 +7,11 @@ import androidx.fragment.app.DialogFragment; import com.afollestad.materialdialogs.MaterialDialog; import com.kabouzeid.gramophone.R; +import com.kabouzeid.gramophone.interfaces.MediaCallback; import com.kabouzeid.gramophone.model.Playlist; import com.kabouzeid.gramophone.model.Song; import com.kabouzeid.gramophone.util.PlaylistUtil; +import com.kabouzeid.gramophone.util.QueryUtil; import java.util.ArrayList; import java.util.List; @@ -26,8 +28,10 @@ public class AddToPlaylistDialog extends DialogFragment { @NonNull public static AddToPlaylistDialog create(List songs) { AddToPlaylistDialog dialog = new AddToPlaylistDialog(); + Bundle args = new Bundle(); args.putParcelableArrayList("songs", new ArrayList<>(songs)); + dialog.setArguments(args); return dialog; } @@ -35,19 +39,11 @@ public class AddToPlaylistDialog extends DialogFragment { @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - final List playlists = new ArrayList<>(); - - CharSequence[] playlistNames = new CharSequence[playlists.size() + 1]; - playlistNames[0] = getActivity().getResources().getString(R.string.action_new_playlist); - for (int i = 1; i < playlistNames.length; i++) { - playlistNames[i] = playlists.get(i - 1).name; - } - - return new MaterialDialog.Builder(getActivity()) + List playlists = new ArrayList<>(); + MaterialDialog dialog = new MaterialDialog.Builder(getActivity()) .title(R.string.action_add_to_playlist) - .items(playlistNames) + .items(getActivity().getResources().getString(R.string.action_new_playlist)) .itemsCallback((materialDialog, view, i, charSequence) -> { - // noinspection unchecked final List songs = getArguments().getParcelableArrayList("songs"); if (songs == null) return; @@ -60,5 +56,22 @@ public class AddToPlaylistDialog extends DialogFragment { } }) .build(); + + QueryUtil.getPlaylists(new MediaCallback() { + @Override + public void onLoadMedia(List media) { + playlists.addAll((List) media); + + CharSequence[] names = new CharSequence[playlists.size() + 1]; + names[0] = getActivity().getResources().getString(R.string.action_new_playlist); + for (int i = 0; i < playlists.size(); i++) { + names[i + 1] = playlists.get(i).name; + } + + dialog.setItems(names); + } + }); + + return dialog; } } diff --git a/app/src/main/java/com/kabouzeid/gramophone/dialogs/CreatePlaylistDialog.java b/app/src/main/java/com/kabouzeid/gramophone/dialogs/CreatePlaylistDialog.java index 49784e00..4b210c4d 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/dialogs/CreatePlaylistDialog.java +++ b/app/src/main/java/com/kabouzeid/gramophone/dialogs/CreatePlaylistDialog.java @@ -27,8 +27,7 @@ public class CreatePlaylistDialog extends DialogFragment { @NonNull public static CreatePlaylistDialog create(@Nullable Song song) { List list = new ArrayList<>(); - if (song != null) - list.add(song); + if (song != null) list.add(song); return create(list); } @@ -53,7 +52,7 @@ public class CreatePlaylistDialog extends DialogFragment { final String name = charSequence.toString().trim(); if (getActivity() == null || getArguments() == null || name.isEmpty()) return; List songs = getArguments().getParcelableArrayList(SONGS); - if (songs != null && !songs.isEmpty()) { + if (songs != null) { PlaylistUtil.createPlaylist(name, songs); } }) diff --git a/app/src/main/java/com/kabouzeid/gramophone/dialogs/RemoveFromPlaylistDialog.java b/app/src/main/java/com/kabouzeid/gramophone/dialogs/RemoveFromPlaylistDialog.java index 7aa6f3f6..12ff54ac 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/dialogs/RemoveFromPlaylistDialog.java +++ b/app/src/main/java/com/kabouzeid/gramophone/dialogs/RemoveFromPlaylistDialog.java @@ -8,6 +8,8 @@ import android.text.Html; import com.afollestad.materialdialogs.MaterialDialog; import com.kabouzeid.gramophone.R; +import com.kabouzeid.gramophone.model.Playlist; +import com.kabouzeid.gramophone.model.PlaylistSong; import com.kabouzeid.gramophone.model.Song; import com.kabouzeid.gramophone.util.PlaylistUtil; @@ -26,8 +28,10 @@ public class RemoveFromPlaylistDialog extends DialogFragment { @NonNull public static RemoveFromPlaylistDialog create(List songs) { RemoveFromPlaylistDialog dialog = new RemoveFromPlaylistDialog(); + Bundle args = new Bundle(); args.putParcelableArrayList("songs", new ArrayList<>(songs)); + dialog.setArguments(args); return dialog; } @@ -36,6 +40,7 @@ public class RemoveFromPlaylistDialog extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { final List songs = getArguments().getParcelableArrayList("songs"); + int title; CharSequence content; if (songs.size() > 1) { @@ -53,7 +58,9 @@ public class RemoveFromPlaylistDialog extends DialogFragment { .negativeText(android.R.string.cancel) .onPositive((dialog, which) -> { if (getActivity() == null) return; - PlaylistUtil.deleteItems(songs, songs.get(0).id); + + PlaylistSong song = (PlaylistSong) songs.get(0); + PlaylistUtil.deleteItems(songs, song.playlistId); }) .build(); } diff --git a/app/src/main/java/com/kabouzeid/gramophone/model/PlaylistSong.java b/app/src/main/java/com/kabouzeid/gramophone/model/PlaylistSong.java new file mode 100644 index 00000000..c1bde992 --- /dev/null +++ b/app/src/main/java/com/kabouzeid/gramophone/model/PlaylistSong.java @@ -0,0 +1,42 @@ +package com.kabouzeid.gramophone.model; + +import android.os.Parcel; + +import org.jellyfin.apiclient.model.dto.BaseItemDto; + +public class PlaylistSong extends Song { + public final String playlistId; + + public PlaylistSong(BaseItemDto itemDto, String playlistId) { + super(itemDto); + this.playlistId = playlistId; + } + + public PlaylistSong(String id, String title, int trackNumber, int year, long duration, String albumId, String albumName, String artistId, String artistName, final String playlistId) { + super("", title, trackNumber, year, duration, "", albumName, "", artistName); + this.playlistId = playlistId; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + + dest.writeString(this.playlistId); + } + + protected PlaylistSong(Parcel in) { + super(in); + + this.playlistId = in.readString(); + } + + public static final Creator CREATOR = new Creator() { + public PlaylistSong createFromParcel(Parcel source) { + return new PlaylistSong(source); + } + + public PlaylistSong[] newArray(int size) { + return new PlaylistSong[size]; + } + }; +} diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/PlaylistDetailActivity.java b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/PlaylistDetailActivity.java index 9e2f357c..2c396627 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/PlaylistDetailActivity.java +++ b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/PlaylistDetailActivity.java @@ -26,10 +26,10 @@ import com.kabouzeid.gramophone.helper.menu.PlaylistMenuHelper; import com.kabouzeid.gramophone.interfaces.CabHolder; import com.kabouzeid.gramophone.interfaces.MediaCallback; import com.kabouzeid.gramophone.model.Playlist; +import com.kabouzeid.gramophone.model.PlaylistSong; import com.kabouzeid.gramophone.model.Song; import com.kabouzeid.gramophone.model.playlist.AbsSmartPlaylist; import com.kabouzeid.gramophone.ui.activities.base.AbsSlidingMusicPanelActivity; -import com.kabouzeid.gramophone.util.QueryUtil; import com.kabouzeid.gramophone.util.ThemeUtil; import com.kabouzeid.gramophone.util.PlaylistUtil; import com.kabouzeid.gramophone.util.ViewUtil; @@ -80,10 +80,10 @@ public class PlaylistDetailActivity extends AbsSlidingMusicPanelActivity impleme ItemQuery query = new ItemQuery(); query.setParentId(playlist.id); - QueryUtil.getSongs(query, new MediaCallback() { + PlaylistUtil.getPlaylist(query, new MediaCallback() { @Override public void onLoadMedia(List media) { - adapter.getDataSet().addAll((List) media); + adapter.getDataSet().addAll((List) media); adapter.notifyDataSetChanged(); } }); diff --git a/app/src/main/java/com/kabouzeid/gramophone/util/PlaylistUtil.java b/app/src/main/java/com/kabouzeid/gramophone/util/PlaylistUtil.java index d21043b9..5c4d5e02 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/util/PlaylistUtil.java +++ b/app/src/main/java/com/kabouzeid/gramophone/util/PlaylistUtil.java @@ -1,17 +1,46 @@ package com.kabouzeid.gramophone.util; import com.kabouzeid.gramophone.App; +import com.kabouzeid.gramophone.interfaces.MediaCallback; import com.kabouzeid.gramophone.model.Playlist; +import com.kabouzeid.gramophone.model.PlaylistSong; import com.kabouzeid.gramophone.model.Song; import org.jellyfin.apiclient.interaction.EmptyResponse; import org.jellyfin.apiclient.interaction.Response; +import org.jellyfin.apiclient.model.dto.BaseItemDto; import org.jellyfin.apiclient.model.playlists.PlaylistCreationRequest; +import org.jellyfin.apiclient.model.querying.ItemQuery; +import org.jellyfin.apiclient.model.querying.ItemsResult; import java.util.ArrayList; import java.util.List; public class PlaylistUtil { + public static void getPlaylist(ItemQuery query, MediaCallback callback) { + query.setIncludeItemTypes(new String[]{"Audio"}); + query.setUserId(App.getApiClient().getCurrentUserId()); + query.setLimit(100); + query.setRecursive(true); + if (QueryUtil.currentLibrary != null && query.getParentId() == null) query.setParentId(QueryUtil.currentLibrary.getId()); + App.getApiClient().GetItemsAsync(query, new Response() { + @Override + public void onResponse(ItemsResult result) { + List songs = new ArrayList<>(); + for (BaseItemDto itemDto : result.getItems()) { + songs.add(new PlaylistSong(itemDto, query.getParentId())); + } + + callback.onLoadMedia(songs); + } + + @Override + public void onError(Exception exception) { + exception.printStackTrace(); + } + }); + } + public static void createPlaylist(final String name, final List songs) { ArrayList ids = new ArrayList<>(); for (Song song : songs) { @@ -21,7 +50,7 @@ public class PlaylistUtil { PlaylistCreationRequest request = new PlaylistCreationRequest(); request.setUserId(App.getApiClient().getCurrentUserId()); request.setName(name); - request.setItemIdList(ids); + if (ids.size() != 0) request.setItemIdList(ids); App.getApiClient().CreatePlaylist(request, new Response<>()); } @@ -54,5 +83,23 @@ public class PlaylistUtil { } public static void renamePlaylist(final String playlist, final String name) { + String user = App.getApiClient().getCurrentUserId(); + App.getApiClient().GetItemAsync(playlist, user, new Response() { + @Override + public void onResponse(BaseItemDto itemDto) { + itemDto.setName(name); + renamePlaylistInner(itemDto); + } + + @Override + public void onError(Exception exception) { + exception.printStackTrace(); + } + }); + } + + public static void renamePlaylistInner(final BaseItemDto itemDto) { + // TODO find a method to upload metadata changes + // at some point this could become metadata utilities } } \ No newline at end of file diff --git a/app/src/main/java/com/kabouzeid/gramophone/util/QueryUtil.java b/app/src/main/java/com/kabouzeid/gramophone/util/QueryUtil.java index 86a4c0b4..9f088ffb 100644 --- a/app/src/main/java/com/kabouzeid/gramophone/util/QueryUtil.java +++ b/app/src/main/java/com/kabouzeid/gramophone/util/QueryUtil.java @@ -23,6 +23,8 @@ import java.util.List; public class QueryUtil { public static BaseItemDto currentLibrary; + // TODO return BaseItemDto everywhere + // will simplify the code for the getPlaylists method public static void getLibraries(MediaCallback callback) { String id = App.getApiClient().getCurrentUserId(); App.getApiClient().GetUserViews(id, new Response() {