From 20d7f3452119f991a7bc74a0527f78fb13b43899 Mon Sep 17 00:00:00 2001 From: Anonymous Raccoon <32224410+AnonymusRaccoon@users.noreply.github.com> Date: Wed, 28 Feb 2018 20:30:37 +0100 Subject: [PATCH] Solving Theme Bug. --- MusicApp/MainActivity.cs | 6 +- MusicApp/MusicApp.csproj | 4 +- .../Resources/Portable Class/Preferences.cs | 6 +- MusicApp/Resources/Portable Class/Queue.cs | 7 +- .../Portable Class/RecyclerAdapter.cs | 2 +- MusicApp/Resources/Portable Class/Sleeper.cs | 16 +- .../Resources/Portable Class/YoutubeEngine.cs | 238 +++++++++++++++++- MusicApp/packages.config | 2 +- 8 files changed, 261 insertions(+), 20 deletions(-) diff --git a/MusicApp/MainActivity.cs b/MusicApp/MainActivity.cs index c639f87..a68bc76 100644 --- a/MusicApp/MainActivity.cs +++ b/MusicApp/MainActivity.cs @@ -87,13 +87,12 @@ namespace MusicApp ISharedPreferences pref = PreferenceManager.GetDefaultSharedPreferences(this); SwitchTheme(pref.GetInt("theme", 1)); SetContentView(Resource.Layout.Main); - Song song = (Song) Intent.GetStringExtra("Song"); instance = this; var bottomNavigation = FindViewById(Resource.Id.bottomView); bottomNavigation.NavigationItemSelected += PreNavigate; - ToolBar = (Android.Support.V7.Widget.Toolbar) FindViewById(Resource.Id.toolbar); + ToolBar = (Android.Support.V7.Widget.Toolbar)FindViewById(Resource.Id.toolbar); SetSupportActionBar(ToolBar); SupportActionBar.Title = "MusicApp"; @@ -267,7 +266,7 @@ namespace MusicApp public void Scroll(object sender, View.ScrollChangeEventArgs e) { if(!Queue.instance.adapter.RefreshDisabled()) - contentRefresh.SetEnabled(((LinearLayoutManager)Queue.instance.ListView.GetLayoutManager()).FindFirstVisibleItemPosition() == 0); + contentRefresh.SetEnabled(((LinearLayoutManager)Queue.instance.ListView.GetLayoutManager()).FindFirstCompletelyVisibleItemPosition() == 0); if(((LinearLayoutManager)Queue.instance.ListView.GetLayoutManager()).FindLastCompletelyVisibleItemPosition() == Queue.instance.adapter.songList.Count) { @@ -449,6 +448,7 @@ namespace MusicApp private void Navigate(int layout) { + Console.WriteLine("&Navigate"); Android.Support.V4.App.Fragment fragment = null; switch (layout) { diff --git a/MusicApp/MusicApp.csproj b/MusicApp/MusicApp.csproj index e528b87..4660c6b 100644 --- a/MusicApp/MusicApp.csproj +++ b/MusicApp/MusicApp.csproj @@ -202,8 +202,8 @@ ..\packages\Xamarin.Auth.1.5.0.3\lib\MonoAndroid10\Xamarin.Auth.dll - - ..\packages\YoutubeExplode.4.1.0\lib\netstandard2.0\YoutubeExplode.dll + + ..\packages\YoutubeExplode.4.1.1\lib\netstandard2.0\YoutubeExplode.dll diff --git a/MusicApp/Resources/Portable Class/Preferences.cs b/MusicApp/Resources/Portable Class/Preferences.cs index 9aba139..395ca3e 100644 --- a/MusicApp/Resources/Portable Class/Preferences.cs +++ b/MusicApp/Resources/Portable Class/Preferences.cs @@ -209,8 +209,10 @@ namespace MusicApp.Resources.Portable_Class Preference prefButton = FindPreference("theme"); prefButton.Summary = args.Which == 0 ? "White Theme" : "Dark Theme"; - MainActivity.Theme = args.Which; - MainActivity.dialogTheme = args.Which == 0 ? Resource.Style.AppCompatAlertDialogStyle : Resource.Style.AppCompatDarkAlertDialogStyle; + MainActivity.instance.SwitchTheme(args.Which); + MainActivity.instance.Recreate(); + //MainActivity.Theme = args.Which; + //MainActivity.dialogTheme = args.Which == 0 ? Resource.Style.AppCompatAlertDialogStyle : Resource.Style.AppCompatDarkAlertDialogStyle; Activity.Recreate(); }); builder.Show(); diff --git a/MusicApp/Resources/Portable Class/Queue.cs b/MusicApp/Resources/Portable Class/Queue.cs index 065c5a6..5813201 100644 --- a/MusicApp/Resources/Portable Class/Queue.cs +++ b/MusicApp/Resources/Portable Class/Queue.cs @@ -1,4 +1,5 @@ using Android.OS; +using Android.Support.Design.Widget; using Android.Support.V4.App; using Android.Support.V7.Widget; using Android.Support.V7.Widget.Helper; @@ -80,7 +81,7 @@ namespace MusicApp.Resources.Portable_Class return view; isEmpty = true; - AddEmptyView(); + return LayoutInflater.Inflate(Resource.Layout.NoQueue, container, false); } return view; } @@ -166,11 +167,11 @@ namespace MusicApp.Resources.Portable_Class builder.Show(); } - public void RemoveFromQueue(Song item) + public static void RemoveFromQueue(Song item) { if(item == MusicPlayer.queue[MusicPlayer.CurrentID()]) { - //Make snackbar + Snackbar.Make(MainActivity.instance.FindViewById(Resource.Id.snackBar), "You are trying to remove the current music from the queue.", Snackbar.LengthShort).Show(); return; } diff --git a/MusicApp/Resources/Portable Class/RecyclerAdapter.cs b/MusicApp/Resources/Portable Class/RecyclerAdapter.cs index 6e0e501..3985bf5 100644 --- a/MusicApp/Resources/Portable Class/RecyclerAdapter.cs +++ b/MusicApp/Resources/Portable Class/RecyclerAdapter.cs @@ -176,7 +176,7 @@ namespace MusicApp.Resources.Portable_Class public void ItemDismissed(int position) { Console.WriteLine("&Swiped"); - Queue.instance.RemoveFromQueue(songList[position]); + Queue.RemoveFromQueue(songList[position]); NotifyItemRemoved(position); } diff --git a/MusicApp/Resources/Portable Class/Sleeper.cs b/MusicApp/Resources/Portable Class/Sleeper.cs index 91cd6fc..77a50bc 100644 --- a/MusicApp/Resources/Portable Class/Sleeper.cs +++ b/MusicApp/Resources/Portable Class/Sleeper.cs @@ -13,6 +13,8 @@ namespace MusicApp.Resources.Portable_Class public static Sleeper instance; public int timer; + private bool stoped = false; + public override IBinder OnBind(Intent intent) { return null; @@ -29,7 +31,16 @@ namespace MusicApp.Resources.Portable_Class if (instance == null) StartTimer(intent); else - timer = intent.GetIntExtra("time", timer); + { + int time = intent.GetIntExtra("time", timer); + if (time == 0) + { + stoped = true; + StopForeground(true); + } + else + timer = time; + } return StartCommandResult.Sticky; } @@ -54,6 +65,9 @@ namespace MusicApp.Resources.Portable_Class await Task.Delay(60000); // One minute in ms timer -= 1; + + if (stoped) + return; } Intent musicIntent = new Intent(Application.Context, typeof(MusicPlayer)); diff --git a/MusicApp/Resources/Portable Class/YoutubeEngine.cs b/MusicApp/Resources/Portable Class/YoutubeEngine.cs index 905e664..2bb9a94 100644 --- a/MusicApp/Resources/Portable Class/YoutubeEngine.cs +++ b/MusicApp/Resources/Portable Class/YoutubeEngine.cs @@ -1,6 +1,8 @@ using Android.Content; +using Android.Database; using Android.OS; using Android.Preferences; +using Android.Provider; using Android.Support.Design.Widget; using Android.Support.V4.App; using Android.Support.V7.App; @@ -186,8 +188,24 @@ namespace MusicApp.Resources.Portable_Class builder.Show(); } - public static async void Play(string videoID, string title, string artist, string thumbnailURL) + public static async void Play(string videoID, string title, string artist, string thumbnailURL, bool skipExistVerification = false) { + if (!skipExistVerification && FileIsAlreadyDownloaded(videoID)) + { + Context context = Android.App.Application.Context; + Intent mIntent = new Intent(context, typeof(MusicPlayer)); + mIntent.PutExtra("file", GetLocalPathFromYTID(videoID)); + mIntent.SetAction("Play"); + context.StartService(mIntent); + int localID = MusicPlayer.queue.Count; + + Snackbar.Make(MainActivity.instance.FindViewById(Resource.Id.snackBar), title + " has been downloaded on your device. Playing the local file instead of the online one.", Snackbar.LengthShort).SetAction("Play the youtube file anyway.", (v) => + { + Queue.RemoveFromQueue(MusicPlayer.queue[localID]); + Play(videoID, title, artist, thumbnailURL, true); + }).Show(); + } + ProgressBar parseProgress = MainActivity.instance.FindViewById(Resource.Id.ytProgress); parseProgress.Visibility = ViewStates.Visible; parseProgress.ScaleY = 6; @@ -210,12 +228,78 @@ namespace MusicApp.Resources.Portable_Class MainActivity.instance.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.contentView, Player.NewInstance()).Commit(); } - public static async void PlayFiles(Song[] files) + public static async void PlayFiles(Song[] files, bool skipExistVerification = false) { if (files.Length < 1) return; - Play(files[0].GetPath(), files[0].GetName(), files[0].GetArtist(), files[0].GetAlbum()); + if (!skipExistVerification) + { + List index = new List(); + List downloadedSong = new List(); + for (int i = 0; i < files.Length; i++) + { + if (FileIsAlreadyDownloaded(files[i].youtubeID)) + { + index.Add(i); + downloadedSong.Add(files[i]); + } + } + + if (downloadedSong.Count > 0) + { + List filesList = files.ToList(); + + for (int i = 0; i < index.Count; i++) + { + filesList.RemoveAt(index[i]); + } + + files = filesList.ToArray(); + + if (downloadedSong.Count == 1) + { + Context context = Android.App.Application.Context; + Intent intent = new Intent(context, typeof(MusicPlayer)); + intent.PutExtra("file", GetLocalPathFromYTID(downloadedSong[0].youtubeID)); + intent.SetAction("PlayLast"); + context.StartService(intent); + int localID = MusicPlayer.queue.Count; + + Snackbar.Make(MainActivity.instance.FindViewById(Resource.Id.snackBar), downloadedSong[0].GetName() + " has been downloaded on your device. Playing the local file instead of the online one.", Snackbar.LengthShort).SetAction("Play the youtube file anyway.", (v) => + { + Queue.RemoveFromQueue(MusicPlayer.queue[localID]); + MusicPlayer.queue.Insert(MusicPlayer.queue.Count, downloadedSong[0]); + }).Show(); + } + else + { + List localPaths = new List(); + for(int i = 0; i < downloadedSong.Count; i++) + localPaths.Add(GetLocalPathFromYTID(downloadedSong[i].youtubeID)); + + Context context = Android.App.Application.Context; + Intent intent = new Intent(context, typeof(MusicPlayer)); + intent.PutStringArrayListExtra("files", localPaths.ToArray()); + intent.PutExtra("clearQueue", false); + intent.SetAction("RandomPlay"); + context.StartService(intent); + int localID = MusicPlayer.queue.Count; + + Snackbar.Make(MainActivity.instance.FindViewById(Resource.Id.snackBar), downloadedSong.Count + " files are on your device. Playing locals files instead of the online version.", Snackbar.LengthShort).SetAction("Play youtube files anyway", (v) => + { + for (int i = 0; i < downloadedSong.Count; i++) + { + Queue.RemoveFromQueue(MusicPlayer.queue[localID + i]); + MusicPlayer.queue.Insert(MusicPlayer.CurrentID() + i, downloadedSong[i]); + } + + }).Show(); + } + } + } + + Play(files[0].GetPath(), files[0].GetName(), files[0].GetArtist(), files[0].GetAlbum(), true); if (files.Length < 2) return; @@ -229,8 +313,24 @@ namespace MusicApp.Resources.Portable_Class } - public static async void PlayNext(string videoID, string title, string artist, string thumbnailURL) + public static async void PlayNext(string videoID, string title, string artist, string thumbnailURL, bool skipExistVerification = false) { + if (!skipExistVerification && FileIsAlreadyDownloaded(videoID)) + { + Context context = Android.App.Application.Context; + Intent mIntent = new Intent(context, typeof(MusicPlayer)); + mIntent.PutExtra("file", GetLocalPathFromYTID(videoID)); + mIntent.SetAction("PlayNext"); + context.StartService(mIntent); + int localID = MusicPlayer.queue.Count; + + Snackbar.Make(MainActivity.instance.FindViewById(Resource.Id.snackBar), title + " has been downloaded on your device. Playing the local file instead of the online one.", Snackbar.LengthShort).SetAction("Play the youtube file anyway.", (v) => + { + Queue.RemoveFromQueue(MusicPlayer.queue[localID]); + PlayNext(videoID, title, artist, thumbnailURL, true); + }).Show(); + } + ProgressBar parseProgress = MainActivity.instance.FindViewById(Resource.Id.ytProgress); parseProgress.Visibility = ViewStates.Visible; parseProgress.ScaleY = 6; @@ -251,8 +351,25 @@ namespace MusicApp.Resources.Portable_Class parseProgress.Visibility = ViewStates.Gone; } - public static async void PlayLast(string videoID, string title, string artist, string thumbnailURL) + public static async void PlayLast(string videoID, string title, string artist, string thumbnailURL, bool skipExistVerification = false) { + if (!skipExistVerification && FileIsAlreadyDownloaded(videoID)) + { + Context context = Android.App.Application.Context; + Intent mIntent = new Intent(context, typeof(MusicPlayer)); + mIntent.PutExtra("file", GetLocalPathFromYTID(videoID)); + mIntent.SetAction("PlayLast"); + context.StartService(mIntent); + int localID = MusicPlayer.queue.Count; + + Snackbar.Make(MainActivity.instance.FindViewById(Resource.Id.snackBar), title + " has been downloaded on your device. Playing the local file instead of the online one.", Snackbar.LengthShort).SetAction("Play the youtube file anyway.", (v) => + { + Queue.RemoveFromQueue(MusicPlayer.queue[localID]); + PlayLast(videoID, title, artist, thumbnailURL, true); + }).Show(); + } + + ProgressBar parseProgress = MainActivity.instance.FindViewById(Resource.Id.ytProgress); parseProgress.Visibility = ViewStates.Visible; parseProgress.ScaleY = 6; @@ -273,11 +390,19 @@ namespace MusicApp.Resources.Portable_Class parseProgress.Visibility = ViewStates.Gone; } - public async static void Download(string name, string videoID) + public async static void Download(string name, string videoID, bool skipExistVerification = false) { ISharedPreferences prefManager = PreferenceManager.GetDefaultSharedPreferences(Android.App.Application.Context); if (prefManager.GetString("downloadPath", null) != null) { + if (FileIsAlreadyDownloaded(videoID) && !skipExistVerification) + { + Snackbar.Make(MainActivity.instance.FindViewById(Resource.Id.snackBar), name + " is already on your device.", Snackbar.LengthShort).SetAction("Download Anyway", (v) => + { + Download(name, videoID, true); + }).Show(); + } + Toast.MakeText(Android.App.Application.Context, "Downloading...", ToastLength.Short).Show(); Context context = Android.App.Application.Context; Intent intent = new Intent(context, typeof(Downloader)); @@ -299,11 +424,57 @@ namespace MusicApp.Resources.Portable_Class } } - public static async void DownloadFiles(string[] names, string[] videoIDs) + public static async void DownloadFiles(string[] names, string[] videoIDs, bool skipExistVerification = false) { ISharedPreferences prefManager = PreferenceManager.GetDefaultSharedPreferences(Android.App.Application.Context); if (prefManager.GetString("downloadPath", null) != null) { + if (!skipExistVerification) + { + List downloadedName = new List(); + List downloadedID = new List(); + for (int i = 0; i < names.Length; i++) + { + if (FileIsAlreadyDownloaded(videoIDs[i])) + { + downloadedName.Add(names[i]); + downloadedID.Add(videoIDs[i]); + } + } + + if (downloadedName.Count > 0) + { + List namesList = names.ToList(); + List idList = videoIDs.ToList(); + + for(int i = 0; i < downloadedName.Count; i++) + { + namesList.Remove(downloadedName[i]); + idList.Remove(downloadedID[i]); + } + + names = namesList.ToArray(); + videoIDs = idList.ToArray(); + + if (downloadedName.Count == 1) + { + Snackbar.Make(MainActivity.instance.FindViewById(Resource.Id.snackBar), downloadedName[0] + " is already on your device.", Snackbar.LengthShort).SetAction("Download this file anyway", (v) => + { + Downloader.instance.Download(new DownloadFile(downloadedName[0], downloadedID[0])); + }).Show(); + } + else + { + Snackbar.Make(MainActivity.instance.FindViewById(Resource.Id.snackBar), downloadedName.Count + " files are already on your device", Snackbar.LengthShort).SetAction("Download all this files anyway", (v) => + { + for(int i = 0; i < downloadedName.Count; i++) + Downloader.instance.Download(new DownloadFile(downloadedName[i], downloadedID[i])); + + }).Show(); + } + } + } + Toast.MakeText(Android.App.Application.Context, "Downloading...", ToastLength.Short).Show(); Context context = Android.App.Application.Context; Intent intent = new Intent(context, typeof(Downloader)); @@ -327,6 +498,59 @@ namespace MusicApp.Resources.Portable_Class } } + public static bool FileIsAlreadyDownloaded(string youtubeID) + { + Android.Net.Uri musicUri = MediaStore.Audio.Media.ExternalContentUri; + + CursorLoader cursorLoader = new CursorLoader(Android.App.Application.Context, musicUri, null, null, null, null); + ICursor musicCursor = (ICursor)cursorLoader.LoadInBackground(); + + if (musicCursor != null && musicCursor.MoveToFirst()) + { + int youtubeKey = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Composer); + do + { + string ytID = musicCursor.GetString(youtubeKey); + if(ytID == youtubeID) + { + musicCursor.Close(); + return true; + } + } + while (musicCursor.MoveToNext()); + musicCursor.Close(); + } + + return false; + } + + public static string GetLocalPathFromYTID(string videoID) + { + Android.Net.Uri musicUri = MediaStore.Audio.Media.ExternalContentUri; + CursorLoader cursorLoader = new CursorLoader(Android.App.Application.Context, musicUri, null, null, null, null); + ICursor musicCursor = (ICursor)cursorLoader.LoadInBackground(); + + if (musicCursor != null && musicCursor.MoveToFirst()) + { + int youtubeKey = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Composer); + int pathKey = musicCursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Data); + do + { + string ytID = musicCursor.GetString(youtubeKey); + string path = musicCursor.GetString(pathKey); + if (ytID == videoID) + { + musicCursor.Close(); + return path; + } + } + while (musicCursor.MoveToNext()); + musicCursor.Close(); + } + + return null; + } + public static void RemoveFromPlaylist(string videoID) { youtubeService.PlaylistItems.Delete(videoID).Execute(); diff --git a/MusicApp/packages.config b/MusicApp/packages.config index c863c02..e4bfa5d 100644 --- a/MusicApp/packages.config +++ b/MusicApp/packages.config @@ -89,5 +89,5 @@ - + \ No newline at end of file