work on item deletion from playlists
This commit is contained in:
parent
3ca2b750ff
commit
930f7e8aa3
8 changed files with 131 additions and 22 deletions
|
|
@ -19,13 +19,12 @@ import com.kabouzeid.gramophone.util.ViewUtil;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public class OrderablePlaylistSongAdapter extends PlaylistSongAdapter implements DraggableItemAdapter<OrderablePlaylistSongAdapter.ViewHolder> {
|
public class OrderablePlaylistSongAdapter extends PlaylistSongAdapter implements DraggableItemAdapter<OrderablePlaylistSongAdapter.ViewHolder> {
|
||||||
|
|
||||||
private OnMoveItemListener onMoveItemListener;
|
private OnMoveItemListener onMoveItemListener;
|
||||||
|
|
||||||
public OrderablePlaylistSongAdapter(@NonNull AppCompatActivity activity, @NonNull List<Song> dataSet, @LayoutRes int itemLayoutRes, boolean usePalette, @Nullable CabHolder cabHolder, @Nullable OnMoveItemListener onMoveItemListener) {
|
public OrderablePlaylistSongAdapter(@NonNull AppCompatActivity activity, @NonNull List<Song> dataSet, @LayoutRes int itemLayoutRes, boolean usePalette, @Nullable CabHolder cabHolder, @Nullable OnMoveItemListener onMoveItemListener) {
|
||||||
super(activity, (List<Song>) dataSet, itemLayoutRes, usePalette, cabHolder);
|
super(activity, dataSet, itemLayoutRes, usePalette, cabHolder);
|
||||||
setMultiSelectMenuRes(R.menu.menu_playlists_songs_selection);
|
setMultiSelectMenuRes(R.menu.menu_playlists_songs_selection);
|
||||||
this.onMoveItemListener = onMoveItemListener;
|
this.onMoveItemListener = onMoveItemListener;
|
||||||
}
|
}
|
||||||
|
|
@ -47,7 +46,7 @@ public class OrderablePlaylistSongAdapter extends PlaylistSongAdapter implements
|
||||||
protected void onMultipleItemAction(@NonNull MenuItem menuItem, @NonNull List<Song> selection) {
|
protected void onMultipleItemAction(@NonNull MenuItem menuItem, @NonNull List<Song> selection) {
|
||||||
switch (menuItem.getItemId()) {
|
switch (menuItem.getItemId()) {
|
||||||
case R.id.action_remove_from_playlist:
|
case R.id.action_remove_from_playlist:
|
||||||
RemoveFromPlaylistDialog.create((List<Song>) (List) selection).show(activity.getSupportFragmentManager(), "ADD_PLAYLIST");
|
RemoveFromPlaylistDialog.create(selection).show(activity.getSupportFragmentManager(), "ADD_PLAYLIST");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,11 @@ import androidx.fragment.app.DialogFragment;
|
||||||
|
|
||||||
import com.afollestad.materialdialogs.MaterialDialog;
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
|
import com.kabouzeid.gramophone.interfaces.MediaCallback;
|
||||||
import com.kabouzeid.gramophone.model.Playlist;
|
import com.kabouzeid.gramophone.model.Playlist;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.util.PlaylistUtil;
|
import com.kabouzeid.gramophone.util.PlaylistUtil;
|
||||||
|
import com.kabouzeid.gramophone.util.QueryUtil;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -26,8 +28,10 @@ public class AddToPlaylistDialog extends DialogFragment {
|
||||||
@NonNull
|
@NonNull
|
||||||
public static AddToPlaylistDialog create(List<Song> songs) {
|
public static AddToPlaylistDialog create(List<Song> songs) {
|
||||||
AddToPlaylistDialog dialog = new AddToPlaylistDialog();
|
AddToPlaylistDialog dialog = new AddToPlaylistDialog();
|
||||||
|
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putParcelableArrayList("songs", new ArrayList<>(songs));
|
args.putParcelableArrayList("songs", new ArrayList<>(songs));
|
||||||
|
|
||||||
dialog.setArguments(args);
|
dialog.setArguments(args);
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
@ -35,19 +39,11 @@ public class AddToPlaylistDialog extends DialogFragment {
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
final List<Playlist> playlists = new ArrayList<>();
|
List<Playlist> playlists = new ArrayList<>();
|
||||||
|
MaterialDialog dialog = new MaterialDialog.Builder(getActivity())
|
||||||
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())
|
|
||||||
.title(R.string.action_add_to_playlist)
|
.title(R.string.action_add_to_playlist)
|
||||||
.items(playlistNames)
|
.items(getActivity().getResources().getString(R.string.action_new_playlist))
|
||||||
.itemsCallback((materialDialog, view, i, charSequence) -> {
|
.itemsCallback((materialDialog, view, i, charSequence) -> {
|
||||||
// noinspection unchecked
|
|
||||||
final List<Song> songs = getArguments().getParcelableArrayList("songs");
|
final List<Song> songs = getArguments().getParcelableArrayList("songs");
|
||||||
if (songs == null) return;
|
if (songs == null) return;
|
||||||
|
|
||||||
|
|
@ -60,5 +56,22 @@ public class AddToPlaylistDialog extends DialogFragment {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
QueryUtil.getPlaylists(new MediaCallback() {
|
||||||
|
@Override
|
||||||
|
public void onLoadMedia(List<?> media) {
|
||||||
|
playlists.addAll((List<Playlist>) 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,7 @@ public class CreatePlaylistDialog extends DialogFragment {
|
||||||
@NonNull
|
@NonNull
|
||||||
public static CreatePlaylistDialog create(@Nullable Song song) {
|
public static CreatePlaylistDialog create(@Nullable Song song) {
|
||||||
List<Song> list = new ArrayList<>();
|
List<Song> list = new ArrayList<>();
|
||||||
if (song != null)
|
if (song != null) list.add(song);
|
||||||
list.add(song);
|
|
||||||
return create(list);
|
return create(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,7 +52,7 @@ public class CreatePlaylistDialog extends DialogFragment {
|
||||||
final String name = charSequence.toString().trim();
|
final String name = charSequence.toString().trim();
|
||||||
if (getActivity() == null || getArguments() == null || name.isEmpty()) return;
|
if (getActivity() == null || getArguments() == null || name.isEmpty()) return;
|
||||||
List<Song> songs = getArguments().getParcelableArrayList(SONGS);
|
List<Song> songs = getArguments().getParcelableArrayList(SONGS);
|
||||||
if (songs != null && !songs.isEmpty()) {
|
if (songs != null) {
|
||||||
PlaylistUtil.createPlaylist(name, songs);
|
PlaylistUtil.createPlaylist(name, songs);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ import android.text.Html;
|
||||||
|
|
||||||
import com.afollestad.materialdialogs.MaterialDialog;
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
import com.kabouzeid.gramophone.R;
|
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.model.Song;
|
||||||
import com.kabouzeid.gramophone.util.PlaylistUtil;
|
import com.kabouzeid.gramophone.util.PlaylistUtil;
|
||||||
|
|
||||||
|
|
@ -26,8 +28,10 @@ public class RemoveFromPlaylistDialog extends DialogFragment {
|
||||||
@NonNull
|
@NonNull
|
||||||
public static RemoveFromPlaylistDialog create(List<Song> songs) {
|
public static RemoveFromPlaylistDialog create(List<Song> songs) {
|
||||||
RemoveFromPlaylistDialog dialog = new RemoveFromPlaylistDialog();
|
RemoveFromPlaylistDialog dialog = new RemoveFromPlaylistDialog();
|
||||||
|
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putParcelableArrayList("songs", new ArrayList<>(songs));
|
args.putParcelableArrayList("songs", new ArrayList<>(songs));
|
||||||
|
|
||||||
dialog.setArguments(args);
|
dialog.setArguments(args);
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
@ -36,6 +40,7 @@ public class RemoveFromPlaylistDialog extends DialogFragment {
|
||||||
@Override
|
@Override
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
final List<Song> songs = getArguments().getParcelableArrayList("songs");
|
final List<Song> songs = getArguments().getParcelableArrayList("songs");
|
||||||
|
|
||||||
int title;
|
int title;
|
||||||
CharSequence content;
|
CharSequence content;
|
||||||
if (songs.size() > 1) {
|
if (songs.size() > 1) {
|
||||||
|
|
@ -53,7 +58,9 @@ public class RemoveFromPlaylistDialog extends DialogFragment {
|
||||||
.negativeText(android.R.string.cancel)
|
.negativeText(android.R.string.cancel)
|
||||||
.onPositive((dialog, which) -> {
|
.onPositive((dialog, which) -> {
|
||||||
if (getActivity() == null) return;
|
if (getActivity() == null) return;
|
||||||
PlaylistUtil.deleteItems(songs, songs.get(0).id);
|
|
||||||
|
PlaylistSong song = (PlaylistSong) songs.get(0);
|
||||||
|
PlaylistUtil.deleteItems(songs, song.playlistId);
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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<PlaylistSong> CREATOR = new Creator<PlaylistSong>() {
|
||||||
|
public PlaylistSong createFromParcel(Parcel source) {
|
||||||
|
return new PlaylistSong(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlaylistSong[] newArray(int size) {
|
||||||
|
return new PlaylistSong[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -26,10 +26,10 @@ import com.kabouzeid.gramophone.helper.menu.PlaylistMenuHelper;
|
||||||
import com.kabouzeid.gramophone.interfaces.CabHolder;
|
import com.kabouzeid.gramophone.interfaces.CabHolder;
|
||||||
import com.kabouzeid.gramophone.interfaces.MediaCallback;
|
import com.kabouzeid.gramophone.interfaces.MediaCallback;
|
||||||
import com.kabouzeid.gramophone.model.Playlist;
|
import com.kabouzeid.gramophone.model.Playlist;
|
||||||
|
import com.kabouzeid.gramophone.model.PlaylistSong;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.model.playlist.AbsSmartPlaylist;
|
import com.kabouzeid.gramophone.model.playlist.AbsSmartPlaylist;
|
||||||
import com.kabouzeid.gramophone.ui.activities.base.AbsSlidingMusicPanelActivity;
|
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.ThemeUtil;
|
||||||
import com.kabouzeid.gramophone.util.PlaylistUtil;
|
import com.kabouzeid.gramophone.util.PlaylistUtil;
|
||||||
import com.kabouzeid.gramophone.util.ViewUtil;
|
import com.kabouzeid.gramophone.util.ViewUtil;
|
||||||
|
|
@ -80,10 +80,10 @@ public class PlaylistDetailActivity extends AbsSlidingMusicPanelActivity impleme
|
||||||
|
|
||||||
ItemQuery query = new ItemQuery();
|
ItemQuery query = new ItemQuery();
|
||||||
query.setParentId(playlist.id);
|
query.setParentId(playlist.id);
|
||||||
QueryUtil.getSongs(query, new MediaCallback() {
|
PlaylistUtil.getPlaylist(query, new MediaCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onLoadMedia(List<?> media) {
|
public void onLoadMedia(List<?> media) {
|
||||||
adapter.getDataSet().addAll((List<Song>) media);
|
adapter.getDataSet().addAll((List<PlaylistSong>) media);
|
||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,46 @@
|
||||||
package com.kabouzeid.gramophone.util;
|
package com.kabouzeid.gramophone.util;
|
||||||
|
|
||||||
import com.kabouzeid.gramophone.App;
|
import com.kabouzeid.gramophone.App;
|
||||||
|
import com.kabouzeid.gramophone.interfaces.MediaCallback;
|
||||||
import com.kabouzeid.gramophone.model.Playlist;
|
import com.kabouzeid.gramophone.model.Playlist;
|
||||||
|
import com.kabouzeid.gramophone.model.PlaylistSong;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
|
|
||||||
import org.jellyfin.apiclient.interaction.EmptyResponse;
|
import org.jellyfin.apiclient.interaction.EmptyResponse;
|
||||||
import org.jellyfin.apiclient.interaction.Response;
|
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.playlists.PlaylistCreationRequest;
|
||||||
|
import org.jellyfin.apiclient.model.querying.ItemQuery;
|
||||||
|
import org.jellyfin.apiclient.model.querying.ItemsResult;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class PlaylistUtil {
|
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<ItemsResult>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(ItemsResult result) {
|
||||||
|
List<PlaylistSong> 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<Song> songs) {
|
public static void createPlaylist(final String name, final List<Song> songs) {
|
||||||
ArrayList<String> ids = new ArrayList<>();
|
ArrayList<String> ids = new ArrayList<>();
|
||||||
for (Song song : songs) {
|
for (Song song : songs) {
|
||||||
|
|
@ -21,7 +50,7 @@ public class PlaylistUtil {
|
||||||
PlaylistCreationRequest request = new PlaylistCreationRequest();
|
PlaylistCreationRequest request = new PlaylistCreationRequest();
|
||||||
request.setUserId(App.getApiClient().getCurrentUserId());
|
request.setUserId(App.getApiClient().getCurrentUserId());
|
||||||
request.setName(name);
|
request.setName(name);
|
||||||
request.setItemIdList(ids);
|
if (ids.size() != 0) request.setItemIdList(ids);
|
||||||
App.getApiClient().CreatePlaylist(request, new Response<>());
|
App.getApiClient().CreatePlaylist(request, new Response<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,5 +83,23 @@ public class PlaylistUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renamePlaylist(final String playlist, final String name) {
|
public static void renamePlaylist(final String playlist, final String name) {
|
||||||
|
String user = App.getApiClient().getCurrentUserId();
|
||||||
|
App.getApiClient().GetItemAsync(playlist, user, new Response<BaseItemDto>() {
|
||||||
|
@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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -23,6 +23,8 @@ import java.util.List;
|
||||||
public class QueryUtil {
|
public class QueryUtil {
|
||||||
public static BaseItemDto currentLibrary;
|
public static BaseItemDto currentLibrary;
|
||||||
|
|
||||||
|
// TODO return BaseItemDto everywhere
|
||||||
|
// will simplify the code for the getPlaylists method
|
||||||
public static void getLibraries(MediaCallback callback) {
|
public static void getLibraries(MediaCallback callback) {
|
||||||
String id = App.getApiClient().getCurrentUserId();
|
String id = App.getApiClient().getCurrentUserId();
|
||||||
App.getApiClient().GetUserViews(id, new Response<ItemsResult>() {
|
App.getApiClient().GetUserViews(id, new Response<ItemsResult>() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue