diff --git a/Opus/Code/Api/LocalManager.cs b/Opus/Code/Api/LocalManager.cs index 251e741..f679501 100644 --- a/Opus/Code/Api/LocalManager.cs +++ b/Opus/Code/Api/LocalManager.cs @@ -125,7 +125,7 @@ namespace Opus.Api while (MusicPlayer.instance == null) await Task.Delay(10); - MusicPlayer.instance.AddToQueue(songs.ToArray()); + MusicPlayer.instance.AddToQueue(songs); } /// @@ -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 diff --git a/Opus/Code/Api/PlaylistManager.cs b/Opus/Code/Api/PlaylistManager.cs index 999453e..671a35f 100644 --- a/Opus/Code/Api/PlaylistManager.cs +++ b/Opus/Code/Api/PlaylistManager.cs @@ -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)); } /// @@ -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); } /// @@ -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 tracks = await GetTracksFromLocalPlaylist(LocalID); - MusicPlayer.instance.AddToQueue(tracks.ToArray()); + MusicPlayer.instance.AddToQueue(tracks); } /// @@ -202,7 +202,7 @@ namespace Opus.Api return; } - MusicPlayer.instance.AddToQueue((await GetTracksFromYoutubePlaylist(YoutubeID)).ToArray()); + MusicPlayer.instance.AddToQueue((await GetTracksFromYoutubePlaylist(YoutubeID))); } #endregion diff --git a/Opus/Code/Api/Services/MusicPlayer.cs b/Opus/Code/Api/Services/MusicPlayer.cs index dc8202e..1769a3b 100644 --- a/Opus/Code/Api/Services/MusicPlayer.cs +++ b/Opus/Code/Api/Services/MusicPlayer.cs @@ -868,7 +868,7 @@ namespace Opus.Api.Services } } - public async void AddToQueue(Song[] songs) + public async void AddToQueue(IEnumerable songs) { queue.AddRange(songs); Home.instance?.RefreshQueue(); diff --git a/Opus/Code/Api/SongManager.cs b/Opus/Code/Api/SongManager.cs index c29d52b..2960f1c 100644 --- a/Opus/Code/Api/SongManager.cs +++ b/Opus/Code/Api/SongManager.cs @@ -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); } + + /// + /// Play a list of song in it's default order + /// + /// + public async static void PlayInOrder(List items) + { + Play(items[0]); + items.RemoveAt(0); + + await Task.Delay(1000); + + while (MusicPlayer.instance == null) + await Task.Delay(10); + + MusicPlayer.instance.AddToQueue(items); + } + + /// + /// Play a list of song in a random order + /// + /// + public async static void Shuffle(List 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); + } + + /// + /// Add a list of songs in the queue + /// + /// + public static void AddToQueue(List items) + { + if(MusicPlayer.instance == null || MusicPlayer.queue == null || MusicPlayer.queue.Count == 0) + { + PlayInOrder(items); + return; + } + + MusicPlayer.instance.AddToQueue(items); + } } } \ No newline at end of file diff --git a/Opus/Code/Api/YoutubeManager.cs b/Opus/Code/Api/YoutubeManager.cs index 49433ef..afef28c 100644 --- a/Opus/Code/Api/YoutubeManager.cs +++ b/Opus/Code/Api/YoutubeManager.cs @@ -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 diff --git a/Opus/Code/UI/Adapter/HomeAdapter.cs b/Opus/Code/UI/Adapter/HomeAdapter.cs index 543f99f..68d3501 100644 --- a/Opus/Code/UI/Adapter/HomeAdapter.cs +++ b/Opus/Code/UI/Adapter/HomeAdapter.cs @@ -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(); }; } diff --git a/Opus/Code/UI/Adapter/PlaylistTrackAdapter.cs b/Opus/Code/UI/Adapter/PlaylistTrackAdapter.cs index 7c404cd..be94877 100644 --- a/Opus/Code/UI/Adapter/PlaylistTrackAdapter.cs +++ b/Opus/Code/UI/Adapter/PlaylistTrackAdapter.cs @@ -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(Resource.Id.headerNumber).Text = tracks.Count + " " + (tracks.Count < 2 ? MainActivity.instance.GetString(Resource.String.element) : MainActivity.instance.GetString(Resource.String.elements)); if (!header.FindViewById(Resource.Id.headerPlay).HasOnClickListeners) { - header.FindViewById(Resource.Id.headerPlay).Click += (sender, e0) => { PlaylistManager.PlayInOrder(PlaylistTracks.instance.item); }; + header.FindViewById(Resource.Id.headerPlay).Click += (sender, e0) => { SongManager.PlayInOrder(tracks); }; header.FindViewById(Resource.Id.headerShuffle).Click += (sender, e0) => { - PlaylistManager.Shuffle(PlaylistTracks.instance.item); + SongManager.Shuffle(tracks); }; header.FindViewById(Resource.Id.headerMore).Click += (sender, e0) => { @@ -91,6 +92,10 @@ namespace Opus.Adapter header.FindViewById(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; } diff --git a/Opus/Code/UI/Fragments/Home.cs b/Opus/Code/UI/Fragments/Home.cs index 0d78d39..2e52ebb 100644 --- a/Opus/Code/UI/Fragments/Home.cs +++ b/Opus/Code/UI/Fragments/Home.cs @@ -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 allSongs = new List(); - 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 allSongs = new List(); + 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 songList = allSongs.OrderBy(x => r.Next()).ToList(); + Random r = new Random(); + List 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) diff --git a/Opus/Code/UI/Fragments/PlaylistTracks.cs b/Opus/Code/UI/Fragments/PlaylistTracks.cs index 3536f12..34e03f1 100644 --- a/Opus/Code/UI/Fragments/PlaylistTracks.cs +++ b/Opus/Code/UI/Fragments/PlaylistTracks.cs @@ -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 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 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(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) =>