From e15c2cf2ef7998924278c38496b316703a832d1a Mon Sep 17 00:00:00 2001 From: amazing-username Date: Sat, 15 Jun 2019 10:49:04 -0700 Subject: [PATCH] Added indicator of what song is playing in all of the music-type views. Added Queue data structure to prepare for a music queue. #39 #45 --- Mear/Mear/Playback/MearPlayer.cs | 58 +++++++++++---- Mear/Mear/Utilities/TimeFormat.cs | 9 +-- Mear/Mear/Views/AlbumView.xaml | 2 +- Mear/Mear/Views/AlbumView.xaml.cs | 89 ++++++++++++++++++++++- Mear/Mear/Views/ArtistView.xaml | 2 +- Mear/Mear/Views/ArtistView.xaml.cs | 89 ++++++++++++++++++++++- Mear/Mear/Views/MearPlayerView.xaml.cs | 10 +-- Mear/Mear/Views/MusicLibrary.xaml | 1 - Mear/Mear/Views/MusicViewBase.cs | 17 +++++ Mear/Mear/Views/SongView.xaml | 2 +- Mear/Mear/Views/SongView.xaml.cs | 97 ++++++++++++++++++++++++-- 11 files changed, 336 insertions(+), 40 deletions(-) create mode 100644 Mear/Mear/Views/MusicViewBase.cs diff --git a/Mear/Mear/Playback/MearPlayer.cs b/Mear/Mear/Playback/MearPlayer.cs index ef0f20b..ad01a8b 100644 --- a/Mear/Mear/Playback/MearPlayer.cs +++ b/Mear/Mear/Playback/MearPlayer.cs @@ -20,11 +20,18 @@ using Mear.Utilities; namespace Mear.Playback { - public class MearPlayer - { + public class MearPlayer + { #region Fields + private Queue _mearQueue = null; private static Song _song; private static bool? _initialized = null; + private static SortedDictionary _songChanged = + new SortedDictionary{ + { MusicViews.Song, false }, + { MusicViews.Album, false }, + { MusicViews.Artist, false } + }; #endregion @@ -77,7 +84,10 @@ namespace Mear.Playback } public static async Task ControlMusic(Song song, PlayControls control) { - _song = song; + if (song != null) + { + _song = song; + } switch (control) { case PlayControls.PLAYOFFLINE: @@ -113,15 +123,16 @@ namespace Mear.Playback return null; } + public static async Task SongTitle() + { + return _song.Title; + } public static async Task ConvertToTime() { try { var ttlSec = (int)CrossMediaManager.Current.Position.TotalSeconds; - var cnvrt = new TimeFormat(); - var curPos = cnvrt.ConvertToSongTime(ttlSec); - - return curPos; + return TimeFormat.ConvertToSongTime(ttlSec); } catch (Exception ex) { @@ -161,7 +172,7 @@ namespace Mear.Playback { var songPath = song.SongPath; - await CrossMediaManager.Current.Play(songPath); + PlaySong(songPath); } catch (Exception ex) { @@ -179,6 +190,10 @@ namespace Mear.Playback _song.Downloaded = false; } + public static async Task ResetSongChange(MusicViews type) + { + _songChanged[type] = false; + } public static async Task SeekTo(double songProress) { double newPosition = (songProress / 100) * ((double)_song.Duration); @@ -222,6 +237,10 @@ namespace Mear.Playback { return CrossMediaManager.Current.IsPlaying(); } + public static bool SongHasBeenChanged(MusicViews type) + { + return _songChanged[type].Value; + } public static bool RepeatMatchedDatabase() { var playerRepeatMode = CrossMediaManager.Current.RepeatMode; @@ -301,9 +320,11 @@ namespace Mear.Playback if (_initialized == null) { CrossMediaManager.Current.MediaItemFinished += Current_MediaItemFinished; - //BackgroundWork(); _initialized = true; } + _songChanged[MusicViews.Song] = true; + _songChanged[MusicViews.Album] = true; + _songChanged[MusicViews.Artist] = true; } private static async Task ResumeSong() { @@ -314,7 +335,7 @@ namespace Mear.Playback { var musicCtrl = new DBMusicControlsRepository(); musicCtrl.UpdateRepeat(); - var repeatMode = (Repeat)musicCtrl.IsRepeatOn(); + var repeatMode = musicCtrl.IsRepeatOn(); CrossMediaManager.Current.RepeatMode = RepeatUtility.RetrieveRepeatMode(repeatMode); } @@ -341,15 +362,12 @@ namespace Mear.Playback { var ctrlRepo = new DBMusicControlsRepository(); var repeatMode = ctrlRepo.IsRepeatOn(); - if (CrossMediaManager.Current.IsPlaying()) - { - //return; - } + switch(repeatMode) { case Repeat.ONE: CrossMediaManager.Current.SeekToStart(); - //PlaySong(_song.SongPath); + PlaySong(_song.SongPath); break; case Repeat.ALL: // Will implment this fully later once Queues are a feature @@ -359,5 +377,15 @@ namespace Mear.Playback } #endregion #endregion + + + #region Enums + public enum MusicViews + { + Song = 0, + Album, + Artist + } + #endregion } } diff --git a/Mear/Mear/Utilities/TimeFormat.cs b/Mear/Mear/Utilities/TimeFormat.cs index f756893..9a6d96d 100644 --- a/Mear/Mear/Utilities/TimeFormat.cs +++ b/Mear/Mear/Utilities/TimeFormat.cs @@ -19,23 +19,20 @@ namespace Mear.Utilities #region Methods - public string ConvertToSongTime(int seconds) + public static string ConvertToSongTime(int seconds) { - var curTime = string.Empty; var dur = seconds; var min = TimeSpan.FromSeconds((double) dur).Minutes; var remainingSec = dur % 60; if (remainingSec < 10) { - curTime = $"{min}:0{remainingSec}"; + return $"{min}:0{remainingSec}"; } else { - curTime = $"{min}:{remainingSec}"; + return $"{min}:{remainingSec}"; } - - return curTime; } #endregion } diff --git a/Mear/Mear/Views/AlbumView.xaml b/Mear/Mear/Views/AlbumView.xaml index cbb7413..c895d80 100644 --- a/Mear/Mear/Views/AlbumView.xaml +++ b/Mear/Mear/Views/AlbumView.xaml @@ -11,7 +11,7 @@ - + ConfigureSongIndicatorLayout() + { + var indicatorLayout = new StackLayout(); + indicatorLayout.Orientation = StackOrientation.Horizontal; + indicatorLayout.Padding = 5; + _controlButton = new Button(); + _controlButton.Clicked += ControlButton_Clicked; + _songTitleLabel = new Label(); + _songTitleLabel.HorizontalOptions = LayoutOptions.Center; + _songTitleLabel.VerticalOptions = LayoutOptions.Start; + var isSongPlayer = MearPlayer.IsPlaying(); + + if (isSongPlayer) + { + _controlButton.Text = "P"; + _songTitleLabel.Text = await MearPlayer.SongTitle(); + } + else + { + _controlButton.Text = "S"; + _songTitleLabel.Text = string.Empty; + } + + indicatorLayout.Children.Add(_controlButton); + indicatorLayout.Children.Add(_songTitleLabel); + + return indicatorLayout; + } + + #region Background + private async Task BackgroundControl() + { + try + { + new Thread(async () => + { + while (true) + { + Device.BeginInvokeOnMainThread(async () => + { + if (MearPlayer.SongHasBeenChanged(MearPlayer.MusicViews.Album)) + { + _songTitleLabel.Text = MearPlayer.SongTitle().Result; + MearPlayer.ResetSongChange(MearPlayer.MusicViews.Album); + } + }); + await Task.Delay(800); + } + }).Start(); + } + catch (Exception ex) + { + var msg = ex.Message; + } + } + #endregion + + #region Events + private async void ControlButton_Clicked(object sender, EventArgs e) + { + if (MearPlayer.IsPlaying()) + { + MearPlayer.ControlMusic(null, PlayControls.PAUSE); + } + else + { + MearPlayer.ControlMusic(null, PlayControls.RESUME); + } + } + private void AlbumListView_ItemSelected(object sender, SelectedItemChangedEventArgs e) { var albumItem = (sender as ListView).SelectedItem = null; diff --git a/Mear/Mear/Views/ArtistView.xaml b/Mear/Mear/Views/ArtistView.xaml index 9b6959c..c804db7 100644 --- a/Mear/Mear/Views/ArtistView.xaml +++ b/Mear/Mear/Views/ArtistView.xaml @@ -12,7 +12,7 @@ - + ConfigureSongIndicatorLayout() + { + var indicatorLayout = new StackLayout(); + indicatorLayout.Orientation = StackOrientation.Horizontal; + indicatorLayout.Padding = 5; + _controlButton = new Button(); + _controlButton.Clicked += ControlButton_Clicked; + _songTitleLabel = new Label(); + _songTitleLabel.HorizontalOptions = LayoutOptions.Center; + _songTitleLabel.VerticalOptions = LayoutOptions.Start; + var isSongPlayer = MearPlayer.IsPlaying(); + + if (isSongPlayer) + { + _controlButton.Text = "P"; + _songTitleLabel.Text = await MearPlayer.SongTitle(); + } + else + { + _controlButton.Text = "S"; + _songTitleLabel.Text = string.Empty; + } + + indicatorLayout.Children.Add(_controlButton); + indicatorLayout.Children.Add(_songTitleLabel); + + return indicatorLayout; + } + + #region Background + private async Task BackgroundControl() + { + try + { + new Thread(async () => + { + while (true) + { + Device.BeginInvokeOnMainThread(async () => + { + if (MearPlayer.SongHasBeenChanged(MearPlayer.MusicViews.Artist)) + { + _songTitleLabel.Text = MearPlayer.SongTitle().Result; + MearPlayer.ResetSongChange(MearPlayer.MusicViews.Artist); + } + }); + await Task.Delay(800); + } + }).Start(); + } + catch (Exception ex) + { + var msg = ex.Message; + } + } + #endregion + + #region Events + private async void ControlButton_Clicked(object sender, EventArgs e) + { + if (MearPlayer.IsPlaying()) + { + MearPlayer.ControlMusic(null, PlayControls.PAUSE); + } + else + { + MearPlayer.ControlMusic(null, PlayControls.RESUME); + } + } + private void ArtistListView_ItemSelected(object sender, SelectedItemChangedEventArgs e) { var artistItem = (sender as ListView).SelectedItem = null; diff --git a/Mear/Mear/Views/MearPlayerView.xaml.cs b/Mear/Mear/Views/MearPlayerView.xaml.cs index 51a8071..32401cf 100644 --- a/Mear/Mear/Views/MearPlayerView.xaml.cs +++ b/Mear/Mear/Views/MearPlayerView.xaml.cs @@ -50,7 +50,7 @@ namespace Mear.Views InitializeControls(); BackgroundSongElasping(); - BackgroundSongCoverUpdate(); + //BackgroundSongCoverUpdate(); //BackgroundControlInit(); InitializeOptions(); @@ -81,7 +81,7 @@ namespace Mear.Views return rmvOpt; } - private void InitializeOptions() + private async void InitializeOptions() { if (!_song.Downloaded) { @@ -96,14 +96,10 @@ namespace Mear.Views } private void InitializeControls() { - var songCnvrt = new TimeFormat(); - var dur = _song.Duration; - var endTime = songCnvrt.ConvertToSongTime(dur.Value); - Shuffle.Text = MearPlayer.RetrieveShuffleString(); Repeat.Text = MearPlayer.RetrieveRepeatString(); - EndTime.Text = endTime; + EndTime.Text = TimeFormat.ConvertToSongTime(_song.Duration.Value); } private void RemoveSyncToolbar() { diff --git a/Mear/Mear/Views/MusicLibrary.xaml b/Mear/Mear/Views/MusicLibrary.xaml index f56187c..86c3ba0 100644 --- a/Mear/Mear/Views/MusicLibrary.xaml +++ b/Mear/Mear/Views/MusicLibrary.xaml @@ -46,5 +46,4 @@ - \ No newline at end of file diff --git a/Mear/Mear/Views/MusicViewBase.cs b/Mear/Mear/Views/MusicViewBase.cs new file mode 100644 index 0000000..5f9e07b --- /dev/null +++ b/Mear/Mear/Views/MusicViewBase.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +using Xamarin.Forms; +using Xamarin.Forms.Xaml; + +namespace Mear.Views +{ + [XamlCompilation(XamlCompilationOptions.Compile)] + public partial class MusicViewBase : ContentPage + { + protected void AddPlayerIn(StackLayout mainLayout) + { + } + } +} diff --git a/Mear/Mear/Views/SongView.xaml b/Mear/Mear/Views/SongView.xaml index a23e082..0c35aa4 100644 --- a/Mear/Mear/Views/SongView.xaml +++ b/Mear/Mear/Views/SongView.xaml @@ -12,7 +12,7 @@ - + ConfigureSongIndicatorLayout() + { + var indicatorLayout = new StackLayout(); + indicatorLayout.Orientation = StackOrientation.Horizontal; + indicatorLayout.Padding = 5; + _controlButton = new Button(); + _controlButton.Clicked += ControlButton_Clicked; + _songTitleLabel = new Label(); + _songTitleLabel.HorizontalOptions = LayoutOptions.Center; + _songTitleLabel.VerticalOptions = LayoutOptions.Start; + var isSongPlayer = MearPlayer.IsPlaying(); + + if (isSongPlayer) + { + _controlButton.Text = "P"; + _songTitleLabel.Text = await MearPlayer.SongTitle(); + } + else + { + _controlButton.Text = "S"; + _songTitleLabel.Text = string.Empty; + } + + indicatorLayout.Children.Add(_controlButton); + indicatorLayout.Children.Add(_songTitleLabel); + + return indicatorLayout; + } + + #region Events + private async void ControlButton_Clicked(object sender, EventArgs e) + { + if (MearPlayer.IsPlaying()) + { + MearPlayer.ControlMusic(null, PlayControls.PAUSE); + } + else + { + MearPlayer.ControlMusic(null, PlayControls.RESUME); + } + } + + private async void SongListView_ItemSelected(object sender, SelectedItemChangedEventArgs e) { if (SongListView.SelectedItem == null) { @@ -88,10 +145,38 @@ namespace Mear.Views var msg = ex.Message; } } - #endregion + #endregion - #region Test - public void TestRemoteSong() + #region Background + private async Task BackgroundControl() + { + try + { + new Thread(async () => + { + while (true) + { + Device.BeginInvokeOnMainThread(async () => + { + if (MearPlayer.SongHasBeenChanged(MearPlayer.MusicViews.Song)) + { + _songTitleLabel.Text = MearPlayer.SongTitle().Result; + MearPlayer.ResetSongChange(MearPlayer.MusicViews.Song); + } + }); + await Task.Delay(800); + } + }).Start(); + } + catch (Exception ex) + { + var msg = ex.Message; + } + } + #endregion + + #region Test + public void TestRemoteSong() { var songRepo = new RemoteSongRepository(); var songs = songRepo.RetrieveSongs();