mirror of
https://github.com/zoriya/Opus.git
synced 2025-12-06 06:26:15 +00:00
Reworking playlist download order maangement, trying to solve bugs.
This commit is contained in:
@@ -15,8 +15,6 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using TagLib;
|
||||
using ContentResolver = Android.Content.ContentResolver;
|
||||
using ContentValues = Android.Content.ContentValues;
|
||||
using Intent = Android.Content.Intent;
|
||||
using Random = System.Random;
|
||||
|
||||
@@ -347,56 +345,6 @@ namespace Opus.Api
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an array of local song in a playlist.
|
||||
/// </summary>
|
||||
/// <param name="item">The array of songs you want to add to the playlist. Will only add local file, if you input youtube file in this array, they will be ignored<</param>
|
||||
/// <param name="playList">The name of the playlist</param>
|
||||
/// <param name="LocalID">The id of the local playlist or -1 if you want to add this song to a playlist that will be created after.</param>
|
||||
/// <param name="saveAsSynced">Used only if you want to create a playlist with this method. True if the newly created playlist should be synced on youtube.</param>
|
||||
/// <param name="position">If you want to add the first song to a specific position (should only be used if you know the exact position that you want). Experimental Feature.</param>
|
||||
public async static void AddToPlaylist(Song[] items, string playList, long LocalID, bool saveAsSynced = false, int position = -1)
|
||||
{
|
||||
if (LocalID == -1)
|
||||
{
|
||||
LocalID = await PlaylistManager.GetPlaylistID(playList);
|
||||
if (LocalID == -1)
|
||||
PlaylistManager.CreateLocalPlaylist(playList, items, saveAsSynced, position);
|
||||
else
|
||||
AddToPlaylist(items, playList, LocalID, saveAsSynced, position);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(await MainActivity.instance.GetWritePermission())
|
||||
{
|
||||
int playlistCount = await PlaylistManager.GetPlaylistCount(LocalID);
|
||||
|
||||
ContentResolver resolver = MainActivity.instance.ContentResolver;
|
||||
List<ContentValues> values = new List<ContentValues>();
|
||||
|
||||
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);
|
||||
if(position != -1)
|
||||
{
|
||||
value.Put(MediaStore.Audio.Playlists.Members.PlayOrder, position);
|
||||
position = -1;
|
||||
}
|
||||
else
|
||||
value.Put(MediaStore.Audio.Playlists.Members.PlayOrder, playlistCount + i + 1);
|
||||
values.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
resolver.BulkInsert(MediaStore.Audio.Playlists.Members.GetContentUri("external", LocalID), values.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -20,12 +20,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using static Android.Provider.MediaStore.Audio;
|
||||
using AlertDialog = Android.Support.V7.App.AlertDialog;
|
||||
using CursorLoader = Android.Support.V4.Content.CursorLoader;
|
||||
using Environment = System.Environment;
|
||||
using Path = System.IO.Path;
|
||||
using Playlist = Google.Apis.YouTube.v3.Data.Playlist;
|
||||
using PlaylistItem = Opus.DataStructure.PlaylistItem;
|
||||
using AlertDialog = Android.Support.V7.App.AlertDialog;
|
||||
using Uri = Android.Net.Uri;
|
||||
|
||||
namespace Opus.Api
|
||||
@@ -323,7 +323,7 @@ namespace Opus.Api
|
||||
YoutubeManager.DownloadFiles(new[] { DownloadFile.From(item, playlist.Name) });
|
||||
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||
else
|
||||
LocalManager.AddToPlaylist(new[] { item }, playlist.Name, playlist.LocalID);
|
||||
AddToLocalPlaylist(playlist.LocalID, new[] { item });
|
||||
}
|
||||
if (playlist.YoutubeID != null)
|
||||
YoutubeManager.AddToPlaylist(new[] { item }, playlist.YoutubeID);
|
||||
@@ -522,7 +522,7 @@ namespace Opus.Api
|
||||
public static void StopSyncingDialog(PlaylistItem item, Action UiCallback)
|
||||
{
|
||||
AlertDialog dialog = new AlertDialog.Builder(MainActivity.instance, MainActivity.dialogTheme)
|
||||
.SetTitle(Resource.String.stop_syncing)
|
||||
.SetTitle(MainActivity.instance.GetString(Resource.String.stop_syncing, item.Name))
|
||||
.SetPositiveButton(Resource.String.yes, (sender, e) => { StopSyncing(item); UiCallback?.Invoke(); })
|
||||
.SetNegativeButton(Resource.String.no, (sender, e) => { })
|
||||
.Create();
|
||||
@@ -549,10 +549,11 @@ namespace Opus.Api
|
||||
/// </summary>
|
||||
/// <param name="item">The playlist item</param>
|
||||
/// <param name="song">The song item</param>
|
||||
/// <param name="position">The position of the removed item</param>
|
||||
/// <param name="RemovedCallback">A callback called when the user click ok in the dialog. You just need to remove the track from the UI, everything else is already handled.</param>
|
||||
/// <param name="CancelledCallback">A callback called when the user click cancel in the dialog</param>
|
||||
/// <param name="UndoCallback">A callback called when the user click undo in the snackbar</param>
|
||||
public async static void RemoveTrackFromPlaylistDialog(PlaylistItem item, Song song, Action RemovedCallback, Action CancelledCallback, Action UndoCallback)
|
||||
public async static void RemoveTrackFromPlaylistDialog(PlaylistItem item, Song song, int position, Action RemovedCallback, Action CancelledCallback, Action UndoCallback)
|
||||
{
|
||||
if (!await MainActivity.instance.GetWritePermission())
|
||||
return;
|
||||
@@ -572,15 +573,14 @@ namespace Opus.Api
|
||||
|
||||
RemovedCallback?.Invoke();
|
||||
|
||||
RemoveTrackFromPlaylistCallback callback = new RemoveTrackFromPlaylistCallback(song, item.LocalID);
|
||||
RemoveTrackFromPlaylistCallback callback = new RemoveTrackFromPlaylistCallback(song, item.LocalID, position);
|
||||
Snackbar snackBar = Snackbar.Make(MainActivity.instance.FindViewById(Resource.Id.snackBar), (song.Title.Length > 20 ? song.Title.Substring(0, 17) + "..." : song.Title) + MainActivity.instance.GetString(Resource.String.removed_from_playlist), Snackbar.LengthLong)
|
||||
;
|
||||
// .SetAction(MainActivity.instance.GetString(Resource.String.undo), (v) =>
|
||||
// {
|
||||
// callback.canceled = true;
|
||||
// UndoCallback?.Invoke();
|
||||
// });
|
||||
//snackBar.AddCallback(callback);
|
||||
.SetAction(MainActivity.instance.GetString(Resource.String.undo), (v) =>
|
||||
{
|
||||
callback.canceled = true;
|
||||
UndoCallback?.Invoke();
|
||||
});
|
||||
snackBar.AddCallback(callback);
|
||||
snackBar.View.FindViewById<TextView>(Resource.Id.snackbar_text).SetTextColor(Color.White);
|
||||
snackBar.Show();
|
||||
})
|
||||
@@ -838,7 +838,7 @@ namespace Opus.Api
|
||||
if (Looper.MyLooper() == null)
|
||||
Looper.Prepare();
|
||||
|
||||
CursorLoader cursorLoader = new CursorLoader(Application.Context, musicUri, null, null, null, MediaStore.Audio.Playlists.Members.PlayOrder);
|
||||
CursorLoader cursorLoader = new CursorLoader(Application.Context, musicUri, null, null, null, Playlists.Members.PlayOrder);
|
||||
ICursor musicCursor = (ICursor)cursorLoader.LoadInBackground();
|
||||
|
||||
if (musicCursor != null && musicCursor.MoveToFirst())
|
||||
@@ -848,6 +848,7 @@ namespace Opus.Api
|
||||
int albumID = musicCursor.GetColumnIndex(Media.InterfaceConsts.Album);
|
||||
int thisID = musicCursor.GetColumnIndex(Media.InterfaceConsts.Id);
|
||||
int pathID = musicCursor.GetColumnIndex(Media.InterfaceConsts.Data);
|
||||
int playOrderID = musicCursor.GetColumnIndex(Playlists.Members.PlayOrder);
|
||||
do
|
||||
{
|
||||
string Artist = musicCursor.GetString(artistID);
|
||||
@@ -856,6 +857,7 @@ namespace Opus.Api
|
||||
long AlbumArt = musicCursor.GetLong(musicCursor.GetColumnIndex(Albums.InterfaceConsts.AlbumId));
|
||||
long id = musicCursor.GetLong(thisID);
|
||||
string path = musicCursor.GetString(pathID);
|
||||
string playOrder = musicCursor.GetString(playOrderID);
|
||||
|
||||
if (Title == null)
|
||||
Title = "Unknown Title";
|
||||
@@ -864,7 +866,7 @@ namespace Opus.Api
|
||||
if (Album == null)
|
||||
Album = "Unknow Album";
|
||||
|
||||
songs.Add(new Song(Title, Artist, Album, null, AlbumArt, id, path));
|
||||
songs.Add(new Song(Title, Artist, Album, null, AlbumArt, id, path) { TrackID = playOrder });
|
||||
}
|
||||
while (musicCursor.MoveToNext());
|
||||
musicCursor.Close();
|
||||
@@ -875,16 +877,15 @@ namespace Opus.Api
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will create a local playlist and add an array of songs in this playlist
|
||||
/// Will create a local playlist and add this playlist to the synced array if needed.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the playlist</param>
|
||||
/// <param name="items">The array of songs you want to add. Can be local one or youtube one, it will download them and add them after.</param>
|
||||
/// <param name="syncedPlaylist">True if you want the playlist to be created and synced on youtube too</param>
|
||||
/// <param name="position">Property used only for the downloader, see the LocalManager's AddToPlaylist method to see what it does.</param>
|
||||
public async static void CreateLocalPlaylist(string name, Song[] items, bool syncedPlaylist = false, int position = -1)
|
||||
/// <returns>The id of the playlist will be returned</returns>
|
||||
public async static Task<long> CreateLocalPlaylist(string name, bool syncedPlaylist)
|
||||
{
|
||||
if (!await MainActivity.instance.GetWritePermission())
|
||||
return;
|
||||
return -1;
|
||||
|
||||
//Create the playlist in the local storage db.
|
||||
ContentValues value = new ContentValues();
|
||||
@@ -893,14 +894,6 @@ namespace Opus.Api
|
||||
|
||||
long playlistID = await GetPlaylistID(name);
|
||||
|
||||
if (items != null && items.Length > 0)
|
||||
{
|
||||
LocalManager.AddToPlaylist(items, name, playlistID, false, position); //Will only add files already downloaded
|
||||
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||
YoutubeManager.DownloadFiles(items.ToList().ConvertAll(x => DownloadFile.From(x, name))); //Will download missing files and add them (if there was youtube songs in the items array.
|
||||
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||
}
|
||||
|
||||
if (syncedPlaylist)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
@@ -910,6 +903,30 @@ namespace Opus.Api
|
||||
db.InsertOrReplace(new PlaylistItem(name, playlistID, null));
|
||||
});
|
||||
}
|
||||
|
||||
return playlistID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will create a local playlist and add an array of songs in this playlist
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the playlist</param>
|
||||
/// <param name="items">The array of songs you want to add. Can be local one or youtube one, it will download them and add them after.</param>
|
||||
/// <param name="syncedPlaylist">True if you want the playlist to be created and synced on youtube too</param>
|
||||
public async static void CreateLocalPlaylist(string name, Song[] items, bool syncedPlaylist = false)
|
||||
{
|
||||
long playlistID = await CreateLocalPlaylist(name, syncedPlaylist);
|
||||
|
||||
if (playlistID == -1)
|
||||
return;
|
||||
|
||||
if (items != null && items.Length > 0)
|
||||
{
|
||||
AddToLocalPlaylist(playlistID, items); //Will only add files already downloaded
|
||||
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||
YoutubeManager.DownloadFiles(items.ToList().ConvertAll(x => DownloadFile.From(x, name))); //Will download missing files and add them (if there was youtube songs in the items array.
|
||||
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -970,24 +987,25 @@ namespace Opus.Api
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method will give you the current number of songs in the playlist.
|
||||
/// This method will give you the play order number of last song in the playlist.
|
||||
/// </summary>
|
||||
/// <param name="LocalID"></param>
|
||||
/// <returns></returns>
|
||||
public async static Task<int> GetPlaylistCount(long LocalID)
|
||||
public async static Task<int> GetLastPlayCount(long LocalID)
|
||||
{
|
||||
int count = 0;
|
||||
int playCount = 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);
|
||||
CursorLoader cursorLoader = new CursorLoader(Application.Context, musicUri, null, null, null, Playlists.Members.PlayOrder);
|
||||
ICursor cursor = (ICursor)cursorLoader.LoadInBackground();
|
||||
count = cursor.Count;
|
||||
if(cursor != null && cursor.MoveToLast())
|
||||
playCount = cursor.Count;
|
||||
});
|
||||
return count;
|
||||
return playCount;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -1184,34 +1202,131 @@ namespace Opus.Api
|
||||
|
||||
#region Reorder
|
||||
/// <summary>
|
||||
/// Set the slot of a song in a playlist. Work with local one, youtube one and synced one.
|
||||
/// Get the play slot of a song by giving it's position and it's playlist. (Used for the reorder witch uses these slots)
|
||||
/// </summary>
|
||||
/// <param name="playlist"></param>
|
||||
/// <param name="fromPosition"></param>
|
||||
/// <param name="newPosition"></param>
|
||||
public static void Reorder(PlaylistItem playlist, int fromPosition, int newPosition)
|
||||
/// <param name="LocalID"></param>
|
||||
/// <param name="position"></param>
|
||||
/// <returns></returns>
|
||||
public async static Task<int> GetPlaySlot(long LocalID, int position)
|
||||
{
|
||||
if (playlist.LocalID != 0)
|
||||
Reorder(playlist.LocalID, fromPosition, newPosition);
|
||||
int playSlot = 0;
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (Looper.MyLooper() == null)
|
||||
Looper.Prepare();
|
||||
|
||||
//if (playlist.YoutubeID != null)
|
||||
// Reorder(playlist.YoutubeID, song, newPosition);
|
||||
Uri musicUri = Playlists.Members.GetContentUri("external", LocalID);
|
||||
CursorLoader cursorLoader = new CursorLoader(Application.Context, musicUri, null, null, null, Playlists.Members.PlayOrder);
|
||||
ICursor cursor = (ICursor)cursorLoader.LoadInBackground();
|
||||
if (cursor != null && cursor.MoveToPosition(position))
|
||||
{
|
||||
int playOrderID = cursor.GetColumnIndex(Playlists.Members.PlayOrder);
|
||||
playSlot = cursor.GetInt(playOrderID);
|
||||
Console.WriteLine("&Song: " + cursor.GetString(cursor.GetColumnIndex(Media.InterfaceConsts.Title)) + " Position: " + position + " slot: " + playSlot);
|
||||
}
|
||||
});
|
||||
return playSlot;
|
||||
}
|
||||
|
||||
/// <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)
|
||||
/// <param name="fromSlot">The PlayOrder slot of the song you want to move</param>
|
||||
/// <param name="toSlot">The PlayOrder slot of the target position</param>
|
||||
public async static void Reorder(long PlaylistLocalID, int fromSlot, int toSlot)
|
||||
{
|
||||
if (!await MainActivity.instance.GetWritePermission())
|
||||
return;
|
||||
|
||||
bool success = Playlists.Members.MoveItem(MainActivity.instance.ContentResolver, PlaylistLocalID, fromPosition, newPosition);
|
||||
Console.WriteLine("&Reorder called, fromSlot: " + fromSlot + " toSlot: " + toSlot);
|
||||
bool success = Playlists.Members.MoveItem(MainActivity.instance.ContentResolver, PlaylistLocalID, fromSlot, toSlot);
|
||||
Console.WriteLine("&Reorder success: " + success);
|
||||
}
|
||||
|
||||
public async static void SetQueueSlot(long PlaylistLocalID, long songID, int newSlot)
|
||||
{
|
||||
if (!await MainActivity.instance.GetWritePermission())
|
||||
return;
|
||||
|
||||
Console.WriteLine("&Setting queue slot to: " + newSlot);
|
||||
ContentResolver resolver = MainActivity.instance.ContentResolver;
|
||||
ContentValues value = new ContentValues();
|
||||
value.Put(Playlists.Members.AudioId, songID);
|
||||
value.Put(Playlists.Members.PlayOrder, newSlot);
|
||||
|
||||
resolver.Update(Playlists.Members.GetContentUri("external", PlaylistLocalID), value, Media.InterfaceConsts.Id + "=?", new[] { songID.ToString() });
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Adding
|
||||
/// <summary>
|
||||
/// This method will check if a playlist exist with a specific name and if it doesn't, it will create one.
|
||||
/// </summary>
|
||||
/// <param name="playlistName">The name of the playlist</param>
|
||||
/// <param name="saveAsSynced">True if the newly created playlist should be synced on youtube</param>
|
||||
/// <returns>The id of the playlist.</returns>
|
||||
public async static Task<long> GetOrCreateByName(string playlistName, bool saveAsSynced = false)
|
||||
{
|
||||
long playlistID = await GetPlaylistID(playlistName);
|
||||
if (playlistID == -1)
|
||||
{
|
||||
playlistID = await CreateLocalPlaylist(playlistName, saveAsSynced);
|
||||
}
|
||||
return playlistID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an array of local song in a playlist.
|
||||
/// </summary>
|
||||
/// <param name="LocalID">The id of the local playlist or -1 if you want to add this song to a playlist that will be created after.</param>
|
||||
/// <param name="item">The array of songs you want to add to the playlist. Will only add local file, if you input youtube file in this array, they will be ignored<</param>
|
||||
public async static void AddToLocalPlaylist(long LocalID, Song[] items)
|
||||
{
|
||||
if (await MainActivity.instance.GetWritePermission())
|
||||
{
|
||||
int playlistCount = await GetLastPlayCount(LocalID);
|
||||
|
||||
ContentResolver resolver = MainActivity.instance.ContentResolver;
|
||||
List<ContentValues> values = new List<ContentValues>();
|
||||
|
||||
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(Playlists.Members.AudioId, item.LocalID);
|
||||
value.Put(Playlists.Members.PlayOrder, playlistCount + i + 1);
|
||||
values.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
resolver.BulkInsert(Playlists.Members.GetContentUri("external", LocalID), values.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insert a song to the playlist at a specific position.
|
||||
/// </summary>
|
||||
/// <param name="LocalID">The id of the playlist</param>
|
||||
/// <param name="item">The song item you want to add</param>
|
||||
/// <param name="position">The position of this new item</param>
|
||||
public async static void InsertToLocalPlaylist(long LocalID, Song item, int position)
|
||||
{
|
||||
if (await MainActivity.instance.GetWritePermission())
|
||||
{
|
||||
ContentResolver resolver = MainActivity.instance.ContentResolver;
|
||||
if (item.LocalID != 0 && item.LocalID != -1)
|
||||
{
|
||||
Console.WriteLine("&Adding " + item.Title + " to the playlist with id: " + LocalID);
|
||||
ContentValues value = new ContentValues();
|
||||
value.Put(Playlists.Members.AudioId, item.LocalID);
|
||||
value.Put(Playlists.Members.PlayOrder, position);
|
||||
resolver.Insert(Playlists.Members.GetContentUri("external", LocalID), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ namespace Opus.Api.Services
|
||||
|
||||
public int currentStrike = 0;
|
||||
private static int downloadCount = 0;
|
||||
private static List<string> files = new List<string>();
|
||||
private static readonly List<string> files = new List<string>();
|
||||
private NotificationCompat.Builder notification;
|
||||
private CancellationTokenSource cancellation = new CancellationTokenSource();
|
||||
private const int notificationID = 1001;
|
||||
@@ -309,7 +309,7 @@ namespace Opus.Api.Services
|
||||
int position = queue.FindIndex(x => x.Path == path && x.State == DownloadState.Playlist);
|
||||
if (position != -1)
|
||||
{
|
||||
LocalManager.AddToPlaylist(new[] { await LocalManager.GetSong(path) }, queue[position].PlaylistName, -1, true, position);
|
||||
PlaylistManager.InsertToLocalPlaylist(await PlaylistManager.GetOrCreateByName(queue[position].PlaylistName), await LocalManager.GetSong(path), position + 1);
|
||||
queue[position].State = DownloadState.Completed;
|
||||
|
||||
if (!queue.Exists(x => x.State == DownloadState.None || x.State == DownloadState.Downloading || x.State == DownloadState.Initialization || x.State == DownloadState.MetaData || x.State == DownloadState.Playlist))
|
||||
@@ -321,17 +321,6 @@ namespace Opus.Api.Services
|
||||
else
|
||||
UpdateList(position);
|
||||
}
|
||||
|
||||
|
||||
//if (playlist.IndexOf('/') != -1)
|
||||
//{
|
||||
// playlist = playlist.Substring(0, playlist.IndexOf('/'));
|
||||
// Handler handler = new Handler(MainActivity.instance.MainLooper);
|
||||
// handler.Post(async () =>
|
||||
// {
|
||||
|
||||
// });
|
||||
//}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -353,6 +342,13 @@ namespace Opus.Api.Services
|
||||
Song song = songs.Find(x => x.YoutubeID == files[i].YoutubeID);
|
||||
if (song != null)
|
||||
{
|
||||
//Video is already in the playlist, we want to check if this item has been reordered.
|
||||
if(int.Parse(song.TrackID) != i)
|
||||
{
|
||||
//The plus one is because android playlists have one-based indexes.
|
||||
PlaylistManager.SetQueueSlot(LocalID, song.LocalID, i + 1);
|
||||
}
|
||||
|
||||
//Video is already downloaded:
|
||||
if (files[i].State == DownloadState.None)
|
||||
files[i].State = DownloadState.UpToDate;
|
||||
|
||||
@@ -6,29 +6,31 @@ namespace Opus.Others
|
||||
{
|
||||
public class RemoveTrackFromPlaylistCallback : BaseTransientBottomBar.BaseCallback
|
||||
{
|
||||
private Song song;
|
||||
private readonly Song song;
|
||||
private readonly long LocalPlaylistID;
|
||||
private readonly int position;
|
||||
public bool canceled = false;
|
||||
|
||||
public RemoveTrackFromPlaylistCallback(Song song, long LocalPlaylistID)
|
||||
public RemoveTrackFromPlaylistCallback(Song song, long LocalPlaylistID, int position)
|
||||
{
|
||||
this.song = song;
|
||||
this.LocalPlaylistID = LocalPlaylistID;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public override void OnDismissed(Java.Lang.Object transientBottomBar, int @event)
|
||||
{
|
||||
base.OnDismissed(transientBottomBar, @event);
|
||||
if(!canceled)
|
||||
if(canceled)
|
||||
{
|
||||
MainActivity.instance.SupportFragmentManager.PopBackStack();
|
||||
if (LocalPlaylistID != 0)
|
||||
PlaylistManager.InsertToLocalPlaylist(LocalPlaylistID, song, position);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (song.TrackID != null)
|
||||
{
|
||||
PlaylistManager.RemoveFromYoutubePlaylist(song.TrackID);
|
||||
}
|
||||
}
|
||||
else if (LocalPlaylistID != 0)
|
||||
{
|
||||
LocalManager.AddToPlaylist(new[] { song }, null, LocalPlaylistID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Opus.Adapter
|
||||
/// This is the number of items (for example headers) there is before the list represented by the cursor.
|
||||
/// </summary>
|
||||
public abstract int ItemBefore { get; }
|
||||
public virtual int BaseCount { get { return cursor != null ? cursor.Count : 0; } }
|
||||
public virtual int BaseCount { get { try { return cursor != null ? cursor.Count : 0; } catch { return 0; } } }
|
||||
public override int ItemCount => BaseCount + ItemBefore;
|
||||
|
||||
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
|
||||
|
||||
@@ -53,8 +53,6 @@ namespace Opus.Adapter
|
||||
|
||||
public override void OnBindViewHolder(RecyclerView.ViewHolder viewHolder, int position)
|
||||
{
|
||||
System.Console.WriteLine("&Binding, position: " + position + " BaseCount: " + BaseCount + " ItemCount: " + ItemCount);
|
||||
|
||||
if (position == ItemCount - 1 && !PlaylistTracks.instance.fullyLoadded)
|
||||
{
|
||||
int pad = MainActivity.instance.DpToPx(30);
|
||||
@@ -92,7 +90,6 @@ namespace Opus.Adapter
|
||||
else if (BaseCount == 0)
|
||||
{
|
||||
((TextView)viewHolder.ItemView).Text = MainActivity.instance.GetString(Resource.String.playlist_empty);
|
||||
System.Console.WriteLine("&Binding empty view");
|
||||
}
|
||||
else if (tracks != null)
|
||||
OnBindViewHolder(viewHolder, tracks[position - ItemBefore]);
|
||||
@@ -249,9 +246,15 @@ namespace Opus.Adapter
|
||||
NotifyItemMoved(fromPosition, toPosition);
|
||||
}
|
||||
|
||||
public void ItemMoveEnded(int fromPosition, int toPosition)
|
||||
public async void ItemMoveEnded(int fromPosition, int toPosition)
|
||||
{
|
||||
PlaylistManager.Reorder(PlaylistTracks.instance.item, fromPosition, toPosition);
|
||||
long LocalID = PlaylistTracks.instance.item.LocalID;
|
||||
if (LocalID != 0)
|
||||
{
|
||||
int fromSlot = await PlaylistManager.GetPlaySlot(LocalID, fromPosition) - 1;
|
||||
int toSlot = await PlaylistManager.GetPlaySlot(LocalID, toPosition) - 1;
|
||||
PlaylistManager.Reorder(LocalID, fromSlot, toSlot);
|
||||
}
|
||||
}
|
||||
|
||||
public void ItemDismissed(int position)
|
||||
|
||||
@@ -235,6 +235,7 @@ namespace Opus.Fragments
|
||||
else
|
||||
{
|
||||
await MainActivity.instance.GetWritePermission();
|
||||
int playSlot = await PlaylistManager.GetLastPlayCount(playlistID);
|
||||
|
||||
List<ContentValues> values = new List<ContentValues>();
|
||||
ContentResolver resolver = MainActivity.instance.ContentResolver;
|
||||
@@ -258,8 +259,10 @@ namespace Opus.Fragments
|
||||
|
||||
ContentValues value = new ContentValues();
|
||||
value.Put(MediaStore.Audio.Playlists.Members.AudioId, id);
|
||||
value.Put(MediaStore.Audio.Playlists.Members.PlayOrder, 0);
|
||||
value.Put(MediaStore.Audio.Playlists.Members.PlayOrder, playSlot + 1);
|
||||
values.Add(value);
|
||||
|
||||
playSlot++;
|
||||
}
|
||||
while (musicCursor.MoveToNext());
|
||||
musicCursor.Close();
|
||||
|
||||
@@ -128,7 +128,6 @@ namespace Opus.Fragments
|
||||
|
||||
if (error != null)
|
||||
{
|
||||
System.Console.WriteLine("&Error != null");
|
||||
YoutubePlaylists.Remove(Loading);
|
||||
adapter.NotifyItemRemoved(LocalPlaylists.Count + YoutubePlaylists.Count);
|
||||
YoutubePlaylists.Add(new PlaylistItem("Error", null) { Owner = error, HasWritePermission = yt != null }); //I use this to check witch error is called. Not really clean but it'll go.
|
||||
@@ -458,21 +457,21 @@ namespace Opus.Fragments
|
||||
{
|
||||
PlaylistManager.StopSyncingDialog(item, () =>
|
||||
{
|
||||
PlaylistItem LocalPlaylist = new PlaylistItem(YoutubePlaylists[Position - LocalPlaylists.Count].Name, item.LocalID, YoutubePlaylists[Position - LocalPlaylists.Count].Count);
|
||||
LocalPlaylists.Add(LocalPlaylist);
|
||||
if (LocalPlaylists.Count == 3 && LocalPlaylists[1].Name == "EMPTY")
|
||||
{
|
||||
LocalPlaylists.RemoveAt(1);
|
||||
adapter.NotifyItemChanged(1);
|
||||
}
|
||||
else
|
||||
adapter.NotifyItemInserted(LocalPlaylists.Count);
|
||||
|
||||
YoutubePlaylists[Position - LocalPlaylists.Count].LocalID = 0;
|
||||
YoutubePlaylists[Position - LocalPlaylists.Count].SyncState = SyncState.False;
|
||||
PlaylistHolder holder = (PlaylistHolder)ListView.GetChildViewHolder(ListView.GetChildAt(Position));
|
||||
holder.sync.Visibility = ViewStates.Gone;
|
||||
holder.SyncLoading.Visibility = ViewStates.Gone;
|
||||
|
||||
PlaylistItem LocalPlaylist = new PlaylistItem(YoutubePlaylists[Position - LocalPlaylists.Count].Name, item.LocalID, YoutubePlaylists[Position - LocalPlaylists.Count].Count);
|
||||
if (LocalPlaylists.Count == 2 && LocalPlaylists[1].Name == "EMPTY")
|
||||
{
|
||||
LocalPlaylists.RemoveAt(1);
|
||||
adapter.NotifyItemRemoved(1);
|
||||
}
|
||||
|
||||
LocalPlaylists.Add(LocalPlaylist);
|
||||
adapter.NotifyItemInserted(LocalPlaylists.Count);
|
||||
});
|
||||
bottomSheet.Dismiss();
|
||||
})});
|
||||
|
||||
@@ -348,9 +348,15 @@ namespace Opus.Fragments
|
||||
Uri musicUri = Playlists.Members.GetContentUri("external", item.LocalID);
|
||||
string selection;
|
||||
if (query != null)
|
||||
{
|
||||
selection = Media.InterfaceConsts.Title + " LIKE \"%" + query + "%\" OR " + Media.InterfaceConsts.Artist + " LIKE \"%" + query + "%\"";
|
||||
isInEditMode = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
selection = null;
|
||||
isInEditMode = true;
|
||||
}
|
||||
|
||||
return new CursorLoader(Android.App.Application.Context, musicUri, null, selection, null, Playlists.Members.PlayOrder);
|
||||
}
|
||||
@@ -540,7 +546,7 @@ namespace Opus.Fragments
|
||||
|
||||
public void RemoveFromPlaylist(Song item, int position)
|
||||
{
|
||||
PlaylistManager.RemoveTrackFromPlaylistDialog(this.item, item, () =>
|
||||
PlaylistManager.RemoveTrackFromPlaylistDialog(this.item, item, position, () =>
|
||||
{
|
||||
if (position == 0)
|
||||
adapter.NotifyItemChanged(0);
|
||||
|
||||
@@ -886,6 +886,9 @@
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\values\customIDs.xml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
<Import Project="..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Animated.Vector.Drawable.targets" Condition="Exists('..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Animated.Vector.Drawable.targets')" />
|
||||
<Import Project="..\packages\Xamarin.Android.Support.v7.Preference.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v7.Preference.targets" Condition="Exists('..\packages\Xamarin.Android.Support.v7.Preference.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v7.Preference.targets')" />
|
||||
|
||||
1884
Opus/Resources/Resource.Designer.cs
generated
1884
Opus/Resources/Resource.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
5
Opus/Resources/values/customIds.xml
Normal file
5
Opus/Resources/values/customIds.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<resources>
|
||||
<item name="download" type="id"/>
|
||||
<item name="fork" type="id"/>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user