Allowing user to reorder songs in playlists.

This commit is contained in:
Anonymus Raccoon
2019-06-12 22:49:07 +02:00
parent 133862bf9a
commit c0852ea8c3
6 changed files with 105 additions and 29 deletions

View File

@@ -369,16 +369,19 @@ namespace Opus.Api
{
if(await MainActivity.instance.GetWritePermission())
{
int playlistCount = await PlaylistManager.GetPlaylistCount(LocalID);
ContentResolver resolver = MainActivity.instance.ContentResolver;
List<ContentValues> values = new List<ContentValues>();
foreach (Song item in items)
for (int i = 0; i < items.Length; i++)
{
Song item = items[i];
if (item != null && item.LocalID != 0 && item.LocalID != -1)
{
ContentValues value = new ContentValues();
value.Put(MediaStore.Audio.Playlists.Members.AudioId, item.LocalID);
value.Put(MediaStore.Audio.Playlists.Members.PlayOrder, 0);
value.Put(MediaStore.Audio.Playlists.Members.PlayOrder, playlistCount + i + 1);
values.Add(value);
}
}

View File

@@ -354,7 +354,6 @@ namespace Opus.Api
{
if (item.YoutubeID == null)
{
Toast.MakeText(MainActivity.instance, Resource.String.playlist_add_song_not_found, ToastLength.Long).Show();
playlists.Remove(Loading);
adapter.NotifyItemRemoved(playlists.Count);
return;
@@ -363,7 +362,7 @@ namespace Opus.Api
if (YoutubeManager.IsUsingAPI || !await MainActivity.instance.WaitForYoutube())
{
Toast.MakeText(MainActivity.instance, Resource.String.youtube_loading_error, ToastLength.Long).Show();
//Toast.MakeText(MainActivity.instance, Resource.String.youtube_loading_error, ToastLength.Long).Show();
playlists.Remove(Loading);
adapter.NotifyItemRemoved(playlists.Count);
return;
@@ -832,9 +831,6 @@ namespace Opus.Api
/// <returns></returns>
public async static Task<List<Song>> GetTracksFromLocalPlaylist(long LocalID)
{
if (Looper.MyLooper() == null)
Looper.Prepare();
List<Song> songs = new List<Song>();
Uri musicUri = Playlists.Members.GetContentUri("external", LocalID);
await Task.Run(() =>
@@ -842,7 +838,7 @@ namespace Opus.Api
if (Looper.MyLooper() == null)
Looper.Prepare();
CursorLoader cursorLoader = new CursorLoader(Application.Context, musicUri, null, null, null, null);
CursorLoader cursorLoader = new CursorLoader(Application.Context, musicUri, null, null, null, MediaStore.Audio.Playlists.Members.PlayOrder);
ICursor musicCursor = (ICursor)cursorLoader.LoadInBackground();
if (musicCursor != null && musicCursor.MoveToFirst())
@@ -971,6 +967,27 @@ namespace Opus.Api
resolver.Delete(uri, Playlists.Members.Id + "=?", new string[] { song.LocalID.ToString() });
//});
}
/// <summary>
/// This method will give you the current number of songs in the playlist.
/// </summary>
/// <param name="LocalID"></param>
/// <returns></returns>
public async static Task<int> GetPlaylistCount(long LocalID)
{
int count = 0;
await Task.Run(() =>
{
if (Looper.MyLooper() == null)
Looper.Prepare();
Uri musicUri = Playlists.Members.GetContentUri("external", LocalID);
CursorLoader cursorLoader = new CursorLoader(Application.Context, musicUri, null, null, null, null);
ICursor cursor = (ICursor)cursorLoader.LoadInBackground();
count = cursor.Count;
});
return count;
}
#endregion
#region YoutubePlaylists
@@ -1163,5 +1180,37 @@ namespace Opus.Api
snackBar.Show();
}
#endregion
#region Reorder
/// <summary>
/// Set the slot of a song in a playlist. Work with local one, youtube one and synced one.
/// </summary>
/// <param name="playlist"></param>
/// <param name="fromPosition"></param>
/// <param name="newPosition"></param>
public static void Reorder(PlaylistItem playlist, int fromPosition, int newPosition)
{
if (playlist.LocalID != 0)
Reorder(playlist.LocalID, fromPosition, newPosition);
//if (playlist.YoutubeID != null)
// Reorder(playlist.YoutubeID, song, newPosition);
}
/// <summary>
/// Set the slot of a song in a local playlist
/// </summary>
/// <param name="PlaylistLocalID"></param>
/// <param name="fromPosition"></param>
/// <param name="newPosition"></param>
public async static void Reorder(long PlaylistLocalID, int fromPosition, int newPosition)
{
if (!await MainActivity.instance.GetWritePermission())
return;
bool success = Playlists.Members.MoveItem(MainActivity.instance.ContentResolver, PlaylistLocalID, fromPosition, newPosition);
Console.WriteLine("&Reorder success: " + success);
}
#endregion
}
}

View File

@@ -10,8 +10,9 @@ namespace Opus.Others
{
public class ItemTouchCallback : ItemTouchHelper.Callback
{
private IItemTouchAdapter adapter;
private readonly IItemTouchAdapter adapter;
private readonly bool alwaysAllowSwap;
private readonly Drawable drawable;
private int from = -1;
private int to = -1;
@@ -36,9 +37,6 @@ namespace Opus.Others
}
}
private Drawable drawable;
public ItemTouchCallback(IItemTouchAdapter adapter, bool alwaysAllowSwap)
{
this.adapter = adapter;

View File

@@ -44,7 +44,7 @@ namespace Opus.Adapter
}
}
public T GetItem(int position)
public virtual T GetItem(int position)
{
cursor.MoveToPosition(position - ItemBefore);
return Convert(cursor);

View File

@@ -125,11 +125,31 @@ namespace Opus.Adapter
else
holder.Live.Visibility = ViewStates.Gone;
if(PlaylistTracks.instance.isInEditMode)
{
holder.more.Visibility = ViewStates.Gone;
holder.reorder.Visibility = ViewStates.Visible;
}
else
{
holder.more.Visibility = ViewStates.Visible;
holder.reorder.Visibility = ViewStates.Gone;
}
if (!holder.more.HasOnClickListeners)
{
holder.more.Click += (sender, e) =>
{
PlaylistTracks.instance.More(tracks == null ? GetItem(holder.AdapterPosition) : tracks[holder.AdapterPosition], holder.AdapterPosition);
PlaylistTracks.instance.More(GetItem(holder.AdapterPosition), holder.AdapterPosition);
};
}
if (!holder.reorder.HasOnClickListeners)
{
holder.reorder.Touch += (sender, e) =>
{
PlaylistTracks.instance.itemTouchHelper.StartDrag(viewHolder);
MainActivity.instance.contentRefresh.Enabled = false;
};
}
@@ -138,12 +158,21 @@ namespace Opus.Adapter
if (MainActivity.Theme == 1)
{
holder.more.SetColorFilter(Color.White);
holder.reorder.SetColorFilter(Color.White);
holder.Title.SetTextColor(Color.White);
holder.Artist.SetTextColor(Color.White);
holder.Artist.Alpha = 0.7f;
}
}
public override Song GetItem(int position)
{
if (tracks == null)
return base.GetItem(position);
else
return tracks[position];
}
public override void OnClick(int position)
{
if (tracks != null && position >= ItemBefore)
@@ -215,13 +244,19 @@ namespace Opus.Adapter
}
public void ItemMoved(int fromPosition, int toPosition) { }
public void ItemMoved(int fromPosition, int toPosition)
{
NotifyItemMoved(fromPosition, toPosition);
}
public void ItemMoveEnded(int fromPosition, int toPosition) { }
public void ItemMoveEnded(int fromPosition, int toPosition)
{
PlaylistManager.Reorder(PlaylistTracks.instance.item, fromPosition, toPosition);
}
public void ItemDismissed(int position)
{
PlaylistTracks.instance.RemoveFromPlaylist(tracks == null ? GetItem(position) : tracks[position], position);
PlaylistTracks.instance.RemoveFromPlaylist(GetItem(position), position);
}
}
}

View File

@@ -31,13 +31,14 @@ namespace Opus.Fragments
public TextView EmptyView;
public RecyclerView ListView;
public PlaylistTrackAdapter adapter;
private Android.Support.V7.Widget.Helper.ItemTouchHelper itemTouchHelper;
public Android.Support.V7.Widget.Helper.ItemTouchHelper itemTouchHelper;
private string query;
private string nextPageToken = null;
public bool fullyLoadded = true;
public bool lastVisible = false;
public bool useHeader = true;
public bool isInEditMode = true;
private bool isForked;
private bool loading = false;
@@ -341,7 +342,7 @@ namespace Opus.Fragments
else
selection = null;
return new CursorLoader(Android.App.Application.Context, musicUri, null, selection, null, null);
return new CursorLoader(Android.App.Application.Context, musicUri, null, selection, null, Playlists.Members.PlayOrder);
}
public void OnLoadFinished(Android.Support.V4.Content.Loader loader, Object data)
@@ -364,16 +365,6 @@ namespace Opus.Fragments
adapter.SwapCursor(null, false);
}
string SongToName(Song song)
{
return song.Title;
}
string SongToYtID(Song song)
{
return song.YoutubeID;
}
public async void OnRefresh(object sender, System.EventArgs e)
{
await PopulateList();