Adding playlists track support for arbitrary song lists. Reworking home.

This commit is contained in:
Tristan Roux
2019-04-23 21:29:47 +02:00
parent a6957224e4
commit 81564ea0fb
9 changed files with 155 additions and 86 deletions

View File

@@ -125,7 +125,7 @@ namespace Opus.Api
while (MusicPlayer.instance == null)
await Task.Delay(10);
MusicPlayer.instance.AddToQueue(songs.ToArray());
MusicPlayer.instance.AddToQueue(songs);
}
/// <summary>
@@ -199,7 +199,7 @@ namespace Opus.Api
MusicPlayer.currentID = startingPosition;
Queue.instance?.RefreshCurrent();
Player.instance?.RefreshPlayer();
MusicPlayer.instance.AddToQueue(tracks.GetRange(startingPosition, tracks.Count - startingPosition).ToArray());
MusicPlayer.instance.AddToQueue(tracks.GetRange(startingPosition, tracks.Count - startingPosition));
}
#endregion

View File

@@ -70,7 +70,7 @@ namespace Opus.Api
MusicPlayer.currentID = startingPosition;
Queue.instance?.RefreshCurrent();
Player.instance?.RefreshPlayer();
MusicPlayer.instance.AddToQueue(tracks.GetRange(startingPosition, tracks.Count - startingPosition).ToArray());
MusicPlayer.instance.AddToQueue(tracks.GetRange(startingPosition, tracks.Count - startingPosition));
}
/// <summary>
@@ -98,7 +98,7 @@ namespace Opus.Api
MusicPlayer.currentID = startingPosition;
Queue.instance?.RefreshCurrent();
Player.instance?.RefreshPlayer();
MusicPlayer.instance.AddToQueue(tracks.GetRange(startingPosition, tracks.Count - startingPosition).ToArray());
MusicPlayer.instance.AddToQueue(tracks.GetRange(startingPosition, tracks.Count - startingPosition));
}
#endregion
@@ -135,7 +135,7 @@ namespace Opus.Api
while (MusicPlayer.instance == null)
await Task.Delay(10);
MusicPlayer.instance.AddToQueue(tracks.ToArray());
MusicPlayer.instance.AddToQueue(tracks);
}
/// <summary>
@@ -157,7 +157,7 @@ namespace Opus.Api
tracks.RemoveAt(playPos);
tracks = tracks.OrderBy(x => r.Next()).ToList();
MusicPlayer.instance.AddToQueue(tracks.ToArray());
MusicPlayer.instance.AddToQueue(tracks);
}
#endregion
@@ -187,7 +187,7 @@ namespace Opus.Api
}
List<Song> tracks = await GetTracksFromLocalPlaylist(LocalID);
MusicPlayer.instance.AddToQueue(tracks.ToArray());
MusicPlayer.instance.AddToQueue(tracks);
}
/// <summary>
@@ -202,7 +202,7 @@ namespace Opus.Api
return;
}
MusicPlayer.instance.AddToQueue((await GetTracksFromYoutubePlaylist(YoutubeID)).ToArray());
MusicPlayer.instance.AddToQueue((await GetTracksFromYoutubePlaylist(YoutubeID)));
}
#endregion

View File

@@ -868,7 +868,7 @@ namespace Opus.Api.Services
}
}
public async void AddToQueue(Song[] songs)
public async void AddToQueue(IEnumerable<Song> songs)
{
queue.AddRange(songs);
Home.instance?.RefreshQueue();

View File

@@ -1,4 +1,9 @@
using Opus.DataStructure;
using Opus.Api.Services;
using Opus.DataStructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Opus.Api
{
@@ -39,5 +44,57 @@ namespace Opus.Api
else
YoutubeManager.PlayLast(item);
}
/// <summary>
/// Play a list of song in it's default order
/// </summary>
/// <param name="items"></param>
public async static void PlayInOrder(List<Song> items)
{
Play(items[0]);
items.RemoveAt(0);
await Task.Delay(1000);
while (MusicPlayer.instance == null)
await Task.Delay(10);
MusicPlayer.instance.AddToQueue(items);
}
/// <summary>
/// Play a list of song in a random order
/// </summary>
/// <param name="items"></param>
public async static void Shuffle(List<Song> items)
{
Random r = new Random();
items = items.OrderBy(x => r.Next()).ToList();
Play(items[0]);
items.RemoveAt(0);
await Task.Delay(1000);
while (MusicPlayer.instance == null)
await Task.Delay(10);
MusicPlayer.instance.AddToQueue(items);
}
/// <summary>
/// Add a list of songs in the queue
/// </summary>
/// <param name="items"></param>
public static void AddToQueue(List<Song> items)
{
if(MusicPlayer.instance == null || MusicPlayer.queue == null || MusicPlayer.queue.Count == 0)
{
PlayInOrder(items);
return;
}
MusicPlayer.instance.AddToQueue(items);
}
}
}

View File

@@ -330,7 +330,7 @@ namespace Opus.Api
while (MusicPlayer.instance == null)
await Task.Delay(100);
MusicPlayer.instance.AddToQueue(tracks.ToArray());
MusicPlayer.instance.AddToQueue(tracks);
MainActivity.instance.ShowPlayer();
Home.instance?.RefreshQueue();
Queue.instance?.Refresh();
@@ -376,7 +376,7 @@ namespace Opus.Api
while (MusicPlayer.instance == null)
await Task.Delay(10);
MusicPlayer.instance.AddToQueue(songs.ToArray());
MusicPlayer.instance.AddToQueue(songs);
}
#endregion

View File

@@ -82,7 +82,7 @@ namespace Opus.Adapter
position = holder.AdapterPosition;
MainActivity.instance.contentRefresh.Refresh -= Home.instance.OnRefresh;
Home.instance = null;
//MainActivity.instance.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.contentView, PlaylistTracks.NewInstance(items[position].contentValue, items[position].SectionTitle)).AddToBackStack(null).Commit();
MainActivity.instance.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.contentView, PlaylistTracks.NewInstance(items[position].contentValue, items[position].SectionTitle)).AddToBackStack(null).Commit();
};
}

View File

@@ -53,26 +53,27 @@ namespace Opus.Adapter
public override void OnBindViewHolder(RecyclerView.ViewHolder viewHolder, int position)
{
System.Console.WriteLine("&Binding at " + position);
System.Console.WriteLine("&ItemCount " + ItemCount);
System.Console.WriteLine("&ItemBefore " + ItemBefore);
System.Console.WriteLine("&ItemAfter " + ItemAfter);
if (position == ItemCount - 1 && !PlaylistTracks.instance.fullyLoadded)
{
int pad = MainActivity.instance.DpToPx(30);
((RecyclerView.LayoutParams)viewHolder.ItemView.LayoutParameters).TopMargin = pad;
((RecyclerView.LayoutParams)viewHolder.ItemView.LayoutParameters).BottomMargin = pad;
}
else if (BaseCount == 0 && position == 0)
{
((TextView)viewHolder.ItemView).Text = MainActivity.instance.GetString(Resource.String.playlist_empty);
}
else if (position == 0 && !PlaylistTracks.instance.useHeader)
{
View header = viewHolder.ItemView;
header.FindViewById<TextView>(Resource.Id.headerNumber).Text = tracks.Count + " " + (tracks.Count < 2 ? MainActivity.instance.GetString(Resource.String.element) : MainActivity.instance.GetString(Resource.String.elements));
if (!header.FindViewById<ImageButton>(Resource.Id.headerPlay).HasOnClickListeners)
{
header.FindViewById<ImageButton>(Resource.Id.headerPlay).Click += (sender, e0) => { PlaylistManager.PlayInOrder(PlaylistTracks.instance.item); };
header.FindViewById<ImageButton>(Resource.Id.headerPlay).Click += (sender, e0) => { SongManager.PlayInOrder(tracks); };
header.FindViewById<ImageButton>(Resource.Id.headerShuffle).Click += (sender, e0) =>
{
PlaylistManager.Shuffle(PlaylistTracks.instance.item);
SongManager.Shuffle(tracks);
};
header.FindViewById<ImageButton>(Resource.Id.headerMore).Click += (sender, e0) =>
{
@@ -91,6 +92,10 @@ namespace Opus.Adapter
header.FindViewById<ImageButton>(Resource.Id.headerMore).ImageTintList = ColorStateList.ValueOf(Color.Black);
}
}
else if (BaseCount == 0)
{
((TextView)viewHolder.ItemView).Text = MainActivity.instance.GetString(Resource.String.playlist_empty);
}
else if (tracks != null)
OnBindViewHolder(viewHolder, tracks[position - ItemBefore]);
else
@@ -151,7 +156,10 @@ namespace Opus.Adapter
public override void Clicked(Song item, int position)
{
PlaylistManager.PlayInOrder(PlaylistTracks.instance.item, position);
if (PlaylistTracks.instance.useHeader)
PlaylistManager.PlayInOrder(PlaylistTracks.instance.item, position);
else
SongManager.Play(item);
}
public override void OnLongClick(int position)
@@ -200,12 +208,12 @@ namespace Opus.Adapter
{
if (position == ItemCount - 1 && !PlaylistTracks.instance.fullyLoadded)
return 1;
else if (BaseCount == 0 && position == 0)
return 3;
if (position == 0 && !PlaylistTracks.instance.useHeader)
else if (position == 0 && !PlaylistTracks.instance.useHeader)
return 2;
return 0;
else if (BaseCount == 0)
return 3;
else
return 0;
}

View File

@@ -80,51 +80,57 @@ namespace Opus.Fragments
HomeSection shuffle = new HomeSection(Resources.GetString(Resource.String.shuffle), SectionType.Shuffle);
adapterItems.Add(shuffle);
if (MainActivity.instance.HasReadPermission())
await Task.Run(() =>
{
Android.Net.Uri musicUri = MediaStore.Audio.Media.ExternalContentUri;
List<Song> allSongs = new List<Song>();
CursorLoader cursorLoader = new CursorLoader(MainActivity.instance, musicUri, null, null, null, null);
ICursor musicCursor = (ICursor)cursorLoader.LoadInBackground();
if (musicCursor != null && musicCursor.MoveToFirst())
if (MainActivity.instance.HasReadPermission())
{
int titleID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Title);
int artistID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Artist);
int albumID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Album);
int thisID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Id);
int pathID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Data);
do
if (Looper.MyLooper() == null)
Looper.Prepare();
Android.Net.Uri musicUri = MediaStore.Audio.Media.ExternalContentUri;
List<Song> allSongs = new List<Song>();
CursorLoader cursorLoader = new CursorLoader(MainActivity.instance, musicUri, null, null, null, null);
ICursor musicCursor = (ICursor)cursorLoader.LoadInBackground();
if (musicCursor != null && musicCursor.MoveToFirst())
{
string Artist = musicCursor.GetString(artistID);
string Title = musicCursor.GetString(titleID);
string Album = musicCursor.GetString(albumID);
long AlbumArt = musicCursor.GetLong(musicCursor.GetColumnIndex(MediaStore.Audio.Albums.InterfaceConsts.AlbumId));
long id = musicCursor.GetLong(thisID);
string path = musicCursor.GetString(pathID);
int titleID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Title);
int artistID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Artist);
int albumID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Album);
int thisID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Id);
int pathID = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Data);
do
{
string Artist = musicCursor.GetString(artistID);
string Title = musicCursor.GetString(titleID);
string Album = musicCursor.GetString(albumID);
long AlbumArt = musicCursor.GetLong(musicCursor.GetColumnIndex(MediaStore.Audio.Albums.InterfaceConsts.AlbumId));
long id = musicCursor.GetLong(thisID);
string path = musicCursor.GetString(pathID);
if (Title == null)
Title = "Unknown Title";
if (Artist == null)
Artist = "Unknow Artist";
if (Album == null)
Album = "Unknow Album";
if (Title == null)
Title = "Unknown Title";
if (Artist == null)
Artist = "Unknow Artist";
if (Album == null)
Album = "Unknow Album";
allSongs.Add(new Song(Title, Artist, Album, null, AlbumArt, id, path));
allSongs.Add(new Song(Title, Artist, Album, null, AlbumArt, id, path));
}
while (musicCursor.MoveToNext());
musicCursor.Close();
}
while (musicCursor.MoveToNext());
musicCursor.Close();
}
Random r = new Random();
List<Song> songList = allSongs.OrderBy(x => r.Next()).ToList();
Random r = new Random();
List<Song> songList = allSongs.OrderBy(x => r.Next()).ToList();
if (songList.Count > 0)
{
HomeSection featured = new HomeSection(Resources.GetString(Resource.String.featured), SectionType.SinglePlaylist, songList.GetRange(0, songList.Count > 50 ? 50 : songList.Count));
adapterItems.Add(featured);
if (songList.Count > 0)
{
HomeSection featured = new HomeSection(Resources.GetString(Resource.String.featured), SectionType.SinglePlaylist, songList.GetRange(0, songList.Count > 50 ? 50 : songList.Count));
adapterItems.Add(featured);
}
}
}
});
view.FindViewById(Resource.Id.loading).Visibility = ViewStates.Gone;
adapter = new HomeAdapter(adapterItems);
@@ -173,10 +179,6 @@ namespace Opus.Fragments
await PopulateView();
}
public void LoadMore()
{
}
public void RefreshQueue(bool scroll = true)
{
if (adapterItems.Count > 0)

View File

@@ -175,7 +175,10 @@ namespace Opus.Fragments
break;
case Resource.Id.addToQueue:
PlaylistManager.AddToQueue(item);
if (useHeader)
PlaylistManager.AddToQueue(item);
else
SongManager.AddToQueue(adapter.tracks);
break;
case Resource.Id.rename:
@@ -223,16 +226,15 @@ namespace Opus.Fragments
menu.Show();
}
//public static Fragment NewInstance(List<Song> songs, string playlistName)
//{
// instance = new PlaylistTracks { Arguments = new Bundle() };
// instance.tracks = songs;
// instance.playlistName = playlistName;
// instance.useHeader = false;
// instance.fullyLoadded = true;
// instance.hasWriteAcess = false;
// return instance;
//}
public static Fragment NewInstance(List<Song> songs, string playlistName)
{
instance = new PlaylistTracks { Arguments = new Bundle() };
instance.item = new PlaylistItem() { Name = playlistName, Count = songs.Count, HasWritePermission = false, LocalID = -1, YoutubeID = null };
instance.useHeader = false;
instance.fullyLoadded = true;
instance.adapter = new PlaylistTrackAdapter(new SearchableList<Song>(songs));
return instance;
}
public static Fragment NewInstance(PlaylistItem item, bool forked)
{
@@ -246,7 +248,7 @@ namespace Opus.Fragments
async Task PopulateList()
{
if (item.LocalID == -1 && item.YoutubeID == ""/* && tracks.Count == 0*/)
if (item.LocalID == -1 && item.YoutubeID == null && adapter?.tracks.Count == 0)
return;
if (item.LocalID != -1)
@@ -311,13 +313,10 @@ namespace Opus.Fragments
MainActivity.instance.Timout();
}
}
//else if(tracks.Count != 0)
//{
// adapter = new PlaylistTrackAdapter(tracks);
// adapter.ItemClick += ListView_ItemClick;
// adapter.ItemLongClick += ListView_ItemLongClick;
// ListView.SetAdapter(adapter);
//}
else if (adapter?.tracks.Count != 0)
{
ListView.SetAdapter(adapter);
}
}
public Android.Support.V4.Content.Loader OnCreateLoader(int id, Bundle args)
@@ -464,7 +463,10 @@ namespace Opus.Fragments
{
new BottomSheetAction(Resource.Drawable.Play, Resources.GetString(Resource.String.play), (sender, eventArg) =>
{
PlaylistManager.PlayInOrder(item, position);
if(useHeader)
PlaylistManager.PlayInOrder(item, position);
else
SongManager.Play(song);
bottomSheet.Dismiss();
}),
new BottomSheetAction(Resource.Drawable.PlaylistPlay, Resources.GetString(Resource.String.play_next), (sender, eventArg) =>