mirror of
https://github.com/zoriya/Opus.git
synced 2025-12-06 06:26:15 +00:00
Finishing the folder track rework.
This commit is contained in:
@@ -76,7 +76,7 @@ namespace Opus.Api
|
||||
if (Looper.MyLooper() == null)
|
||||
Looper.Prepare();
|
||||
|
||||
CursorLoader cursorLoader = new CursorLoader(Application.Context, MediaStore.Audio.Media.ExternalContentUri, null, MediaStore.Audio.Media.InterfaceConsts.Data + " LIKE '%" + folderPath + "%'", null, null);
|
||||
CursorLoader cursorLoader = new CursorLoader(Application.Context, MediaStore.Audio.Media.ExternalContentUri, null, MediaStore.Audio.Media.InterfaceConsts.Data + " LIKE \"%" + folderPath + "%\"", null, null);
|
||||
ICursor musicCursor = (ICursor)cursorLoader.LoadInBackground();
|
||||
if (musicCursor != null && musicCursor.MoveToFirst())
|
||||
{
|
||||
@@ -131,17 +131,24 @@ namespace Opus.Api
|
||||
/// <summary>
|
||||
/// Play all file from a folder in order.
|
||||
/// </summary>
|
||||
/// <param name="folderPath"></param>
|
||||
public async static void PlayInOrder(string folderPath)
|
||||
/// <param name="folderPath">The path of a folder you want to play.</param>
|
||||
/// <param name="startingPosition">The position you want to start playing.</param>
|
||||
/// <param name="customSelection">If you want to have custom selection for your query (can be because the user searched...).</param>
|
||||
public async static void PlayInOrder(string folderPath, int startingPosition = 0, string customSelection = null)
|
||||
{
|
||||
List<Song> songs = new List<Song>();
|
||||
List<Song> tracks = new List<Song>();
|
||||
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (Looper.MyLooper() == null)
|
||||
Looper.Prepare();
|
||||
|
||||
CursorLoader cursorLoader = new CursorLoader(Application.Context, MediaStore.Audio.Media.ExternalContentUri, null, MediaStore.Audio.Media.InterfaceConsts.Data + " LIKE '%" + folderPath + "%'", null, null);
|
||||
CursorLoader cursorLoader;
|
||||
if(customSelection == null)
|
||||
cursorLoader = new CursorLoader(Application.Context, MediaStore.Audio.Media.ExternalContentUri, null, MediaStore.Audio.Media.InterfaceConsts.Data + " LIKE \"%" + folderPath + "%\"", null, null);
|
||||
else
|
||||
cursorLoader = new CursorLoader(Application.Context, MediaStore.Audio.Media.ExternalContentUri, null, customSelection + " AND " + MediaStore.Audio.Media.InterfaceConsts.Data + " LIKE \"%" + folderPath + "%\"", null, null);
|
||||
|
||||
ICursor musicCursor = (ICursor)cursorLoader.LoadInBackground();
|
||||
if (musicCursor != null && musicCursor.MoveToFirst())
|
||||
{
|
||||
@@ -166,14 +173,14 @@ namespace Opus.Api
|
||||
if (Album == null)
|
||||
Album = "Unknow Album";
|
||||
|
||||
songs.Add(new Song(Title, Artist, Album, null, AlbumArt, id, path));
|
||||
tracks.Add(new Song(Title, Artist, Album, null, AlbumArt, id, path));
|
||||
}
|
||||
while (musicCursor.MoveToNext());
|
||||
musicCursor.Close();
|
||||
}
|
||||
});
|
||||
|
||||
if (songs.Count == 0)
|
||||
if (tracks.Count == 0)
|
||||
{
|
||||
Snackbar snackBar = Snackbar.Make(MainActivity.instance.FindViewById<CoordinatorLayout>(Resource.Id.snackBar), Resource.String.no_song_mix, Snackbar.LengthLong);
|
||||
snackBar.View.FindViewById<TextView>(Resource.Id.snackbar_text).SetTextColor(Color.White);
|
||||
@@ -181,15 +188,18 @@ namespace Opus.Api
|
||||
return;
|
||||
}
|
||||
|
||||
songs.Reverse();
|
||||
SongManager.Play(songs[0]);
|
||||
songs.RemoveAt(0);
|
||||
SongManager.Play(tracks[startingPosition]);
|
||||
tracks.RemoveAt(startingPosition);
|
||||
|
||||
await Task.Delay(1000);
|
||||
while (MusicPlayer.instance == null)
|
||||
await Task.Delay(10);
|
||||
|
||||
MusicPlayer.instance.AddToQueue(songs.ToArray());
|
||||
MusicPlayer.instance.InsertToQueue(0, tracks.GetRange(0, startingPosition).ToArray());
|
||||
MusicPlayer.currentID = startingPosition;
|
||||
Queue.instance?.RefreshCurrent();
|
||||
Player.instance?.RefreshPlayer();
|
||||
MusicPlayer.instance.AddToQueue(tracks.GetRange(startingPosition, tracks.Count - startingPosition).ToArray());
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -51,12 +51,12 @@ namespace Opus.Adapter
|
||||
if (position >= ItemBefore)
|
||||
{
|
||||
cursor.MoveToPosition(position - ItemBefore);
|
||||
Clicked(Convert(cursor));
|
||||
Clicked(Convert(cursor), position - ItemBefore);
|
||||
}
|
||||
else
|
||||
HeaderClicked(position);
|
||||
}
|
||||
public abstract void Clicked(T item);
|
||||
public abstract void Clicked(T item, int position);
|
||||
public virtual void HeaderClicked(int position) { }
|
||||
|
||||
public void OnLongClick(int position)
|
||||
@@ -64,12 +64,12 @@ namespace Opus.Adapter
|
||||
if (position >= ItemBefore)
|
||||
{
|
||||
cursor.MoveToPosition(position - ItemBefore);
|
||||
LongClicked(Convert(cursor));
|
||||
LongClicked(Convert(cursor), position - ItemBefore);
|
||||
}
|
||||
else
|
||||
HeaderLongClicked(position);
|
||||
}
|
||||
public abstract void LongClicked(T item);
|
||||
public abstract void LongClicked(T item, int positon);
|
||||
public virtual void HeaderLongClicked(int position) { }
|
||||
|
||||
public abstract T Convert(ICursor cursor);
|
||||
|
||||
@@ -8,6 +8,7 @@ using Opus.Api;
|
||||
using Opus.DataStructure;
|
||||
using Opus.Fragments;
|
||||
using Square.Picasso;
|
||||
using System;
|
||||
|
||||
namespace Opus.Adapter
|
||||
{
|
||||
@@ -16,17 +17,17 @@ namespace Opus.Adapter
|
||||
public bool displayShuffle;
|
||||
public override int ItemBefore => (displayShuffle && BaseCount != 0) ? 1 : 0;
|
||||
|
||||
private Action<Song, int> clickAction;
|
||||
private Action<Song, int> longClickAction;
|
||||
private Action<int> headerAction;
|
||||
|
||||
public BrowseAdapter()
|
||||
public BrowseAdapter(Action<Song, int> clickAction, Action<Song, int> longClickAction, Action<int> headerAction = null)
|
||||
{
|
||||
cursor = null;
|
||||
displayShuffle = true;
|
||||
}
|
||||
|
||||
public BrowseAdapter(ICursor cursor, bool displayShuffle)
|
||||
{
|
||||
this.cursor = cursor;
|
||||
this.displayShuffle = displayShuffle;
|
||||
this.clickAction = clickAction;
|
||||
this.longClickAction = longClickAction;
|
||||
this.headerAction = headerAction;
|
||||
}
|
||||
|
||||
public override void OnBindViewHolder(RecyclerView.ViewHolder viewHolder, int position)
|
||||
@@ -94,18 +95,17 @@ namespace Opus.Adapter
|
||||
|
||||
public override void HeaderClicked(int position)
|
||||
{
|
||||
LocalManager.ShuffleAll();
|
||||
headerAction?.Invoke(position);
|
||||
}
|
||||
|
||||
public override void Clicked(Song song)
|
||||
public override void Clicked(Song song, int position)
|
||||
{
|
||||
song = LocalManager.CompleteItem(song);
|
||||
SongManager.Play(song);
|
||||
clickAction?.Invoke(song, position);
|
||||
}
|
||||
|
||||
public override void LongClicked(Song song)
|
||||
public override void LongClicked(Song song, int position)
|
||||
{
|
||||
Browse.instance?.More(song);
|
||||
longClickAction?.Invoke(song, position);
|
||||
}
|
||||
|
||||
public override Song Convert(ICursor cursor)
|
||||
|
||||
@@ -52,7 +52,17 @@ namespace Opus.Fragments
|
||||
ListView = view.FindViewById<RecyclerView>(Resource.Id.recycler);
|
||||
ListView.SetLayoutManager(new LinearLayoutManager(Android.App.Application.Context));
|
||||
ListView.SetItemAnimator(new DefaultItemAnimator());
|
||||
adapter = new BrowseAdapter();
|
||||
adapter = new BrowseAdapter((song, position) =>
|
||||
{
|
||||
song = LocalManager.CompleteItem(song);
|
||||
SongManager.Play(song);
|
||||
}, (song, position) =>
|
||||
{
|
||||
More(song);
|
||||
}, (position) =>
|
||||
{
|
||||
LocalManager.ShuffleAll();
|
||||
});
|
||||
ListView.SetAdapter(adapter);
|
||||
|
||||
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
|
||||
@@ -86,7 +96,7 @@ namespace Opus.Fragments
|
||||
string selection;
|
||||
if (query != null)
|
||||
{
|
||||
selection = MediaStore.Audio.Media.InterfaceConsts.Title + " LIKE '%" + query + "%' OR " + MediaStore.Audio.Media.InterfaceConsts.Artist + " LIKE '%" + query + "%'";
|
||||
selection = MediaStore.Audio.Media.InterfaceConsts.Title + " LIKE \"%" + query + "%\" OR " + MediaStore.Audio.Media.InterfaceConsts.Artist + " LIKE \"%" + query + "%\"";
|
||||
adapter.displayShuffle = false;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
using Android.Content;
|
||||
using Android.Database;
|
||||
using Android.Net;
|
||||
using Android.OS;
|
||||
using Android.Provider;
|
||||
using Android.Support.Design.Widget;
|
||||
using Android.Support.V4.App;
|
||||
using Android.Support.V7.Widget;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Java.Lang;
|
||||
using Opus.Adapter;
|
||||
using Opus.Api;
|
||||
using Opus.Api.Services;
|
||||
using Opus.DataStructure;
|
||||
using Opus.Others;
|
||||
using Square.Picasso;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using CursorLoader = Android.Support.V4.Content.CursorLoader;
|
||||
|
||||
namespace Opus.Fragments
|
||||
{
|
||||
public class FolderTracks : Fragment
|
||||
public class FolderTracks : Fragment, LoaderManager.ILoaderCallbacks
|
||||
{
|
||||
public static FolderTracks instance;
|
||||
public string folderName;
|
||||
private RecyclerView ListView;
|
||||
private View EmptyView;
|
||||
public BrowseAdapter adapter;
|
||||
public List<Song> result;
|
||||
public string path;
|
||||
|
||||
private List<Song> tracks = new List<Song>();
|
||||
private RecyclerView ListView;
|
||||
public BrowseAdapter adapter;
|
||||
private TextView EmptyView;
|
||||
private string query;
|
||||
|
||||
|
||||
public override void OnActivityCreated(Bundle savedInstanceState)
|
||||
@@ -50,10 +50,22 @@ namespace Opus.Fragments
|
||||
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
||||
{
|
||||
View view = inflater.Inflate(Resource.Layout.CompleteRecycler, container, false);
|
||||
view.FindViewById(Resource.Id.loading).Visibility = ViewStates.Visible;
|
||||
EmptyView = view.FindViewById<TextView>(Resource.Id.empty);
|
||||
ListView = view.FindViewById<RecyclerView>(Resource.Id.recycler);
|
||||
ListView.SetLayoutManager(new LinearLayoutManager(Android.App.Application.Context));
|
||||
ListView.SetItemAnimator(new DefaultItemAnimator());
|
||||
adapter = new BrowseAdapter((song, position) =>
|
||||
{
|
||||
LocalManager.PlayInOrder(path, position, "(" + MediaStore.Audio.Media.InterfaceConsts.Title + " LIKE \"%" + query + "%\" OR " + MediaStore.Audio.Media.InterfaceConsts.Artist + " LIKE \"%" + query + "%\")");
|
||||
}, (song, position) =>
|
||||
{
|
||||
More(song, position);
|
||||
}, (position) =>
|
||||
{
|
||||
LocalManager.ShuffleAll(path);
|
||||
});
|
||||
ListView.SetAdapter(adapter);
|
||||
|
||||
PopulateList();
|
||||
return view;
|
||||
@@ -67,147 +79,60 @@ namespace Opus.Fragments
|
||||
return instance;
|
||||
}
|
||||
|
||||
void PopulateList()
|
||||
async void PopulateList()
|
||||
{
|
||||
//Uri musicUri = MediaStore.Audio.Media.GetContentUriForPath(path);
|
||||
if (await MainActivity.instance.GetReadPermission() == false)
|
||||
{
|
||||
MainActivity.instance.FindViewById(Resource.Id.loading).Visibility = ViewStates.Gone;
|
||||
EmptyView.Visibility = ViewStates.Visible;
|
||||
EmptyView.Text = GetString(Resource.String.no_permission);
|
||||
return;
|
||||
}
|
||||
|
||||
//CursorLoader cursorLoader = new CursorLoader(Android.App.Application.Context, musicUri, null, null, null, null);
|
||||
//ICursor musicCursor = (ICursor)cursorLoader.LoadInBackground();
|
||||
LoaderManager.GetInstance(this).InitLoader(0, null, this);
|
||||
}
|
||||
|
||||
//tracks = new List<Song>();
|
||||
public Android.Support.V4.Content.Loader OnCreateLoader(int id, Bundle args)
|
||||
{
|
||||
Uri musicUri = MediaStore.Audio.Media.ExternalContentUri;
|
||||
string selection;
|
||||
if (query != null)
|
||||
{
|
||||
selection = MediaStore.Audio.Media.InterfaceConsts.Data + " LIKE \"%" + path + "%\" AND (" + MediaStore.Audio.Media.InterfaceConsts.Title + " LIKE \"%" + query + "%\" OR " + MediaStore.Audio.Media.InterfaceConsts.Artist + " LIKE \"%" + query + "%\")";
|
||||
adapter.displayShuffle = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
selection = MediaStore.Audio.Media.InterfaceConsts.Data + " LIKE \"%" + path + "%\"";
|
||||
adapter.displayShuffle = true;
|
||||
}
|
||||
|
||||
//if (musicCursor != null && musicCursor.MoveToFirst())
|
||||
//{
|
||||
// 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 path = musicCursor.GetString(pathID);
|
||||
return new CursorLoader(Android.App.Application.Context, musicUri, null, selection, null, null);
|
||||
}
|
||||
|
||||
// if (!path.Contains(this.path))
|
||||
// continue;
|
||||
public void OnLoadFinished(Android.Support.V4.Content.Loader loader, Object data)
|
||||
{
|
||||
adapter.SwapCursor((ICursor)data);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// if (Title == null)
|
||||
// Title = "Unknown Title";
|
||||
// if (Artist == null)
|
||||
// Artist = "Unknow Artist";
|
||||
// if (Album == null)
|
||||
// Album = "Unknow Album";
|
||||
|
||||
// tracks.Add(new Song(Title, Artist, Album, null, AlbumArt, id, path));
|
||||
// }
|
||||
// while (musicCursor.MoveToNext());
|
||||
// musicCursor.Close();
|
||||
//}
|
||||
|
||||
//adapter = new BrowseAdapter(tracks, false);
|
||||
//adapter.ItemClick += ListView_ItemClick;
|
||||
//adapter.ItemLongCLick += ListView_ItemLongClick;
|
||||
//ListView.SetAdapter(adapter);
|
||||
public void OnLoaderReset(Android.Support.V4.Content.Loader loader)
|
||||
{
|
||||
adapter.SwapCursor(null);
|
||||
}
|
||||
|
||||
private void OnRefresh(object sender, System.EventArgs e)
|
||||
{
|
||||
//tracks.Clear();
|
||||
|
||||
//Uri musicUri = MediaStore.Audio.Media.GetContentUriForPath(path);
|
||||
|
||||
//CursorLoader cursorLoader = new CursorLoader(Android.App.Application.Context, musicUri, null, null, null, null);
|
||||
//ICursor musicCursor = (ICursor)cursorLoader.LoadInBackground();
|
||||
|
||||
|
||||
//if (musicCursor != null && musicCursor.MoveToFirst())
|
||||
//{
|
||||
// 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 path = musicCursor.GetString(pathID);
|
||||
|
||||
// if (!path.Contains(this.path))
|
||||
// continue;
|
||||
|
||||
// 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);
|
||||
|
||||
// if (Title == null)
|
||||
// Title = "Unknown Title";
|
||||
// if (Artist == null)
|
||||
// Artist = "Unknow Artist";
|
||||
// if (Album == null)
|
||||
// Album = "Unknow Album";
|
||||
|
||||
// tracks.Add(new Song(Title, Artist, Album, null, AlbumArt, id, path));
|
||||
// }
|
||||
// while (musicCursor.MoveToNext());
|
||||
// musicCursor.Close();
|
||||
//}
|
||||
|
||||
//adapter = new BrowseAdapter(tracks, false);
|
||||
//adapter.ItemClick += ListView_ItemClick;
|
||||
//adapter.ItemLongCLick += ListView_ItemLongClick;
|
||||
//ListView.SetAdapter(adapter);
|
||||
//MainActivity.instance.contentRefresh.Refreshing = false;
|
||||
adapter.NotifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void Search(string search)
|
||||
{
|
||||
//result = new List<Song>();
|
||||
//foreach (Song item in tracks)
|
||||
//{
|
||||
// if (item.Title.ToLower().Contains(search.ToLower()) || item.Artist.ToLower().Contains(search.ToLower()))
|
||||
// {
|
||||
// result.Add(item);
|
||||
// }
|
||||
//}
|
||||
//adapter = new BrowseAdapter(result, false);
|
||||
//adapter.ItemClick += ListView_ItemClick;
|
||||
//adapter.ItemLongCLick += ListView_ItemLongClick;
|
||||
//ListView.SetAdapter(adapter);
|
||||
}
|
||||
if (search == "")
|
||||
query = null;
|
||||
else
|
||||
query = search;
|
||||
|
||||
private async void ListView_ItemClick(object sender, int position)
|
||||
{
|
||||
Song item = tracks[position];
|
||||
List<Song> queue = tracks.GetRange(position + 1, tracks.Count - position - 1);
|
||||
if (result != null)
|
||||
{
|
||||
item = result[position];
|
||||
queue = result.GetRange(position + 1, result.Count - position - 1);
|
||||
}
|
||||
queue.Reverse();
|
||||
|
||||
SongManager.Play(item);
|
||||
|
||||
while(MusicPlayer.instance == null)
|
||||
await Task.Delay(10);
|
||||
|
||||
foreach(Song song in queue)
|
||||
MusicPlayer.instance.AddToQueue(song);
|
||||
}
|
||||
|
||||
private void ListView_ItemLongClick(object sender, int position)
|
||||
{
|
||||
Song item = tracks[position];
|
||||
if (result != null)
|
||||
item = result[position];
|
||||
|
||||
More(item, position);
|
||||
LoaderManager.GetInstance(this).RestartLoader(0, null, this);
|
||||
}
|
||||
|
||||
public void More(Song item, int position)
|
||||
@@ -231,25 +156,9 @@ namespace Opus.Fragments
|
||||
|
||||
bottomSheet.FindViewById<ListView>(Resource.Id.bsItems).Adapter = new BottomSheetAdapter(MainActivity.instance, Resource.Layout.BottomSheetText, new List<BottomSheetAction>
|
||||
{
|
||||
new BottomSheetAction(Resource.Drawable.Play, Resources.GetString(Resource.String.play), async (sender, eventArg) =>
|
||||
new BottomSheetAction(Resource.Drawable.Play, Resources.GetString(Resource.String.play), (sender, eventArg) =>
|
||||
{
|
||||
int Position = tracks.IndexOf(item);
|
||||
|
||||
List<Song> queue = tracks.GetRange(Position + 1, tracks.Count - Position - 1);
|
||||
if (result != null)
|
||||
{
|
||||
queue = result.GetRange(Position + 1, result.Count - Position - 1);
|
||||
}
|
||||
queue.Reverse();
|
||||
|
||||
SongManager.Play(item);
|
||||
|
||||
while (MusicPlayer.instance == null)
|
||||
await Task.Delay(10);
|
||||
|
||||
foreach (Song song in queue)
|
||||
MusicPlayer.instance.AddToQueue(song);
|
||||
|
||||
LocalManager.PlayInOrder(path, position);
|
||||
bottomSheet.Dismiss();
|
||||
}),
|
||||
new BottomSheetAction(Resource.Drawable.PlaylistPlay, Resources.GetString(Resource.String.play_next), (sender, eventArg) => { SongManager.PlayNext(item); bottomSheet.Dismiss(); }),
|
||||
|
||||
Reference in New Issue
Block a user