-
Notifications
You must be signed in to change notification settings - Fork 730
Dialog for handling duplicate-addition to playlist #375
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package com.kabouzeid.gramophone.dialogs; | ||
|
||
import android.app.Dialog; | ||
import android.content.DialogInterface; | ||
import android.os.Bundle; | ||
import android.support.annotation.NonNull; | ||
import android.support.v4.app.DialogFragment; | ||
import android.text.Html; | ||
|
||
import com.afollestad.materialdialogs.DialogAction; | ||
import com.afollestad.materialdialogs.MaterialDialog; | ||
import com.kabouzeid.gramophone.R; | ||
import com.kabouzeid.gramophone.model.Song; | ||
|
||
import java.util.ArrayList; | ||
|
||
/** | ||
* @author Karim Abou Zeid (kabouzeid) | ||
*/ | ||
public class AddDuplicateToPlaylistDialog extends DialogFragment { | ||
|
||
private int selection = 0; | ||
|
||
private SelectionListener selListener; | ||
|
||
public AddDuplicateToPlaylistDialog() { | ||
selListener = null; | ||
} | ||
|
||
public void setSelListener(SelectionListener SelListener) { | ||
this.selListener = SelListener; | ||
} | ||
public interface SelectionListener { | ||
public void selectedOption(int selection); | ||
} | ||
|
||
@NonNull | ||
public static AddDuplicateToPlaylistDialog create(Song song) { | ||
ArrayList<Song> list = new ArrayList<>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should try to see if you can get this to just be a list of IDs since there is a restriction on the max bundle size. |
||
list.add(song); | ||
return create(list); | ||
} | ||
|
||
@NonNull | ||
public static AddDuplicateToPlaylistDialog create(ArrayList<Song> songs) { | ||
AddDuplicateToPlaylistDialog dialog = new AddDuplicateToPlaylistDialog(); | ||
Bundle args = new Bundle(); | ||
args.putParcelableArrayList("songs", songs); | ||
dialog.setArguments(args); | ||
return dialog; | ||
} | ||
|
||
@NonNull | ||
@Override | ||
public Dialog onCreateDialog(Bundle savedInstanceState) { | ||
//noinspection unchecked | ||
final ArrayList<Song> songs = getArguments().getParcelableArrayList("songs"); | ||
int title; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do the assignments in the same line. |
||
final CharSequence content; | ||
title = R.string.add_duplicate_title; | ||
content = Html.fromHtml(getString(R.string.add_duplicate_msg, songs.get(0).title)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So it only handles the first duplicate? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently for every duplicate a dialog is shown - So actually only one create-Method is required as the ArrayList will never get bigger than 1. |
||
return new MaterialDialog.Builder(getActivity()) | ||
.title(title) | ||
.content(content) | ||
.positiveText(R.string.add_action) | ||
.negativeText(R.string.dont_add_duplicate) | ||
.onNegative(new MaterialDialog.SingleButtonCallback() { | ||
@Override | ||
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { | ||
if (getActivity() == null) return; | ||
selection = 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can't you just directly call the listener? I'm a bit confused as to why it's done this way. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. onDismiss has to be called anyways and by calling the listener in onDismiss it is possible to easily handle cancellation on the dialog e. g. by tapping beside it. |
||
} | ||
}) | ||
.onPositive(new MaterialDialog.SingleButtonCallback() { | ||
@Override | ||
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { | ||
if (getActivity() == null) return; | ||
selection = 1; | ||
} | ||
}) | ||
.build(); | ||
} | ||
|
||
@Override | ||
public void onDismiss(DialogInterface dialog) { | ||
super.onDismiss(dialog); | ||
selListener.selectedOption(selection); | ||
} | ||
|
||
public int getSelection() { | ||
return selection; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,9 +10,11 @@ | |
import android.provider.MediaStore; | ||
import android.support.annotation.NonNull; | ||
import android.support.annotation.Nullable; | ||
import android.support.v7.app.AppCompatActivity; | ||
import android.widget.Toast; | ||
|
||
import com.kabouzeid.gramophone.R; | ||
import com.kabouzeid.gramophone.dialogs.AddDuplicateToPlaylistDialog; | ||
import com.kabouzeid.gramophone.helper.M3UWriter; | ||
import com.kabouzeid.gramophone.model.Playlist; | ||
import com.kabouzeid.gramophone.model.PlaylistSong; | ||
|
@@ -28,7 +30,7 @@ | |
/** | ||
* @author Karim Abou Zeid (kabouzeid) | ||
*/ | ||
public class PlaylistsUtil { | ||
public class PlaylistsUtil extends AddDuplicateToPlaylistDialog { | ||
|
||
public static boolean doesPlaylistExist(@NonNull final Context context, final int playlistId) { | ||
return playlistId != -1 && doesPlaylistExist(context, | ||
|
@@ -99,13 +101,13 @@ public static void deletePlaylists(@NonNull final Context context, @NonNull fina | |
} | ||
} | ||
|
||
public static void addToPlaylist(@NonNull final Context context, final Song song, final int playlistId, final boolean showToastOnFinish) { | ||
public static void addToPlaylist(@NonNull final Context context, final Song song, final int playlistId, final boolean showToastOnFinish, AppCompatActivity activity) { | ||
List<Song> helperList = new ArrayList<>(); | ||
helperList.add(song); | ||
addToPlaylist(context, helperList, playlistId, showToastOnFinish); | ||
addToPlaylist(context, helperList, playlistId, showToastOnFinish, activity); | ||
} | ||
|
||
public static void addToPlaylist(@NonNull final Context context, @NonNull final List<Song> songs, final int playlistId, final boolean showToastOnFinish) { | ||
public static void addToPlaylist(@NonNull final Context context, @NonNull final List<Song> songs, final int playlistId, final boolean showToastOnFinish, AppCompatActivity activity) { | ||
final int size = songs.size(); | ||
final ContentResolver resolver = context.getContentResolver(); | ||
final String[] projection = new String[]{ | ||
|
@@ -128,6 +130,23 @@ public static void addToPlaylist(@NonNull final Context context, @NonNull final | |
} | ||
} | ||
|
||
final int basecopy = base; | ||
for(final Song song: songs) { | ||
if (doPlaylistContains(context, playlistId, song.id)) { | ||
//Toast.makeText(context, song.title+" already in Playlist!", Toast.LENGTH_SHORT).show(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this. |
||
AddDuplicateToPlaylistDialog dialog = AddDuplicateToPlaylistDialog.create(song); | ||
dialog.setSelListener(new AddDuplicateToPlaylistDialog.SelectionListener() { | ||
@Override | ||
public void selectedOption(int selection) { | ||
if (selection == 0) { | ||
removeFromPlaylist(context, song, playlistId, basecopy); | ||
} | ||
} | ||
}); | ||
dialog.show(activity.getSupportFragmentManager(), "DUPLICATE_ADD_PLAYLIST"); | ||
} | ||
} | ||
|
||
int numInserted = 0; | ||
for (int offSet = 0; offSet < size; offSet += 1000) | ||
numInserted += resolver.bulkInsert(uri, makeInsertItems(songs, offSet, 1000, base)); | ||
|
@@ -168,6 +187,17 @@ public static void removeFromPlaylist(@NonNull final Context context, @NonNull f | |
} | ||
} | ||
|
||
public static void removeFromPlaylist(@NonNull final Context context, @NonNull final Song song, int playlistId, int startID) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you explain what the start ID is for? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. startID gets the value of base in case a insertion of a duplicate should be reverted. If you just call the function with a Song every occurence of the song will be deleted. The startID can be passed as the base of the insertion so it is guaranteed that only the recently added song, not the one already inside the playlist will be deleted. (MediaStore.Audio.Playlists.Members.PLAY_ORDER + " >=?" is the query to also find the recently added song in the delete-call) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking about the deletion, it might actually be possible that if you delete a song afterwards all songs with that id will be deleted from the playlist, I will have to test this. |
||
Uri uri = MediaStore.Audio.Playlists.Members.getContentUri( | ||
"external", playlistId); | ||
String selection = MediaStore.Audio.Playlists.Members.AUDIO_ID + " =? AND " + MediaStore.Audio.Playlists.Members.PLAY_ORDER + " >=?"; | ||
String[] selectionArgs = new String[]{String.valueOf(song.id), String.valueOf(startID)}; | ||
try { | ||
context.getContentResolver().delete(uri, selection, selectionArgs); | ||
} catch (SecurityException ignored) { | ||
} | ||
} | ||
|
||
public static void removeFromPlaylist(@NonNull final Context context, @NonNull final List<PlaylistSong> songs) { | ||
final int playlistId = songs.get(0).playlistId; | ||
Uri uri = MediaStore.Audio.Playlists.Members.getContentUri( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -92,6 +92,9 @@ | |
<string name="clear_playlist_title">Clear playlist</string> | ||
<string name="save_playlist_title">Save as file</string> | ||
<string name="add_playlist_title">"Add to playlist"</string> | ||
<string name="add_duplicate_title">"Duplicate in Playlist"</string> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't need the quotes. |
||
<string name="add_duplicate_msg"><![CDATA[Do you want to add <b>%1$s</b> as a duplicate to the playlist?]]></string> | ||
<string name="dont_add_duplicate">Do not add</string> | ||
<string name="action_shuffle_all">Shuffle all</string> | ||
<string name="action_shuffle_album">Shuffle album</string> | ||
<string name="action_shuffle_artist">Shuffle artist</string> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the full name:
setSelectionListener