From: aman.jeph Date: Tue, 28 Sep 2021 13:03:02 +0000 (+0530) Subject: Add 'add to playlist' feature to player view and fix some crash issues X-Git-Tag: submit/tizen/20210929.055951^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=858bf02e05013bd3cf4f0dd340a51a07bfbf2efc;p=profile%2Fiot%2Fapps%2Fdotnet%2Fmusic-player.git Add 'add to playlist' feature to player view and fix some crash issues Change-Id: I7d0103cb6eb03123b6220754e507fe49593cf7f6 Signed-off-by: aman.jeph --- diff --git a/music-player/Common/PlayerCommon.cs b/music-player/Common/PlayerCommon.cs index 360ee2e..b82aafd 100755 --- a/music-player/Common/PlayerCommon.cs +++ b/music-player/Common/PlayerCommon.cs @@ -42,6 +42,12 @@ namespace MusicPlayer.Common PlaybackCompleted, } + public enum PlaylistMemberAddStatus + { + Added, + Cancelled, + }; + public class PlayerEventArgs : EventArgs { private readonly EventType type; diff --git a/music-player/ViewModels/PlayerViewModel.cs b/music-player/ViewModels/PlayerViewModel.cs index e1ea1a1..4f062bb 100755 --- a/music-player/ViewModels/PlayerViewModel.cs +++ b/music-player/ViewModels/PlayerViewModel.cs @@ -264,22 +264,6 @@ namespace MusicPlayer.ViewModels } } - private void UpdatePlayingStatus(PlayingStatus status) - { - playingStatus = status; - switch (status) - { - case PlayingStatus.Playing: - PlayButtonState = PauseState; - break; - case PlayingStatus.Paused: // Fall Through - case PlayingStatus.Stopped: // Fall Through - case PlayingStatus.None: - PlayButtonState = PlayState; - break; - } - } - public void OnCurrentTrackShare() { List trackIdList = new List() @@ -304,6 +288,34 @@ namespace MusicPlayer.ViewModels } } + public PlaylistSelectorViewModel GetPlaylistSelectorViewModel() + { + Track currentTrack = playerModel.CurrentTrack; + if(currentTrack == null) + { + Tizen.Log.Error(AppConstants.LogTag, "Current track is null, so can't create PlaylistSelectorViewModel"); + return null; + } + List trackList = new List() { currentTrack.Id }; + return new PlaylistSelectorViewModel(trackList); + } + + private void UpdatePlayingStatus(PlayingStatus status) + { + playingStatus = status; + switch (status) + { + case PlayingStatus.Playing: + PlayButtonState = PauseState; + break; + case PlayingStatus.Paused: // Fall Through + case PlayingStatus.Stopped: // Fall Through + case PlayingStatus.None: + PlayButtonState = PlayState; + break; + } + } + private void OnPlayingListItemSelected(object sender, PlayingListItemSelectedEvent e) { SetCurrentTrack((Track)e.CurrentSelectedItem); diff --git a/music-player/ViewModels/PlaylistSelectorViewModel.cs b/music-player/ViewModels/PlaylistSelectorViewModel.cs index 11c23d5..c44c67d 100755 --- a/music-player/ViewModels/PlaylistSelectorViewModel.cs +++ b/music-player/ViewModels/PlaylistSelectorViewModel.cs @@ -6,11 +6,12 @@ using MusicPlayer.Common; namespace MusicPlayer.ViewModels { - class PlaylistSelectorViewModel + class PlaylistSelectorViewModel : PropertyNotifier { - public PlaylistSelectorViewModel() + private List addingTrackList; + public PlaylistSelectorViewModel(List trackList) { - PlaylistManager.Instance.PlaylistDataChanged += OnPlaylistDataChanged; + addingTrackList = trackList; List dataList = GeneratePlaylistData(); listViewModel = new ListViewModel(); if (dataList.Count > 0) @@ -28,8 +29,10 @@ namespace MusicPlayer.ViewModels length = UpdateLength(length, count); newName = newName.Substring(0, length); newName += count.ToString(); - if (CheckPlayListName(newName) == true) + if (IsPlaylistExists(newName) == false) + { NewPlayListName = newName; + } } } @@ -40,6 +43,49 @@ namespace MusicPlayer.ViewModels get => listViewModel; } + public string NewPlayListName { get; set; } + + private object playlistSelectedItem; + + public object PlaylistSelectedItem + { + get => playlistSelectedItem; + set => SetProperty(ref playlistSelectedItem, value); + } + + public bool CreatePlaylist(string playlistName) + { + Playlist playlist = PlaylistManager.Instance.GetPlaylist(playlistName); + if (playlist == null) + { + Playlist createdPlaylist = PlaylistManager.Instance.AddPlaylist(playlistName); + if(createdPlaylist != null) + { + PlaylistModel playlistModel = new PlaylistModel(new PlaylistData(createdPlaylist.Id, createdPlaylist.Name, GetTrackCountForPlaylist(createdPlaylist.Id), createdPlaylist.ThumbnailPath)); + listViewModel.Add(playlistModel); + PlaylistSelectedItem = playlistModel; + } + return true; + } + return false; + } + + public bool AddTracksToPlaylist(object selectedItemData) + { + PlaylistModel playlistModel = (PlaylistModel)selectedItemData; + if(addingTrackList == null || addingTrackList.Count <= 0) + { + return false; + } + return PlaylistManager.Instance.AddTracks(playlistModel.PlaylistId, addingTrackList); + } + + public bool IsPlaylistExists(string playlistName) + { + Playlist playlist = PlaylistManager.Instance.GetPlaylist(playlistName); + return playlist == null ? false : true; + } + private List GeneratePlaylistData() { List dataList = new List(); @@ -52,17 +98,15 @@ namespace MusicPlayer.ViewModels { continue; } - Tizen.Log.Debug(AppConstants.LogTag, playlist.Id + ": " + playlist.Name); dataList.Add(new PlaylistData(playlist.Id, playlist.Name, GetTrackCountForPlaylist(playlist.Id), playlist.ThumbnailPath)); } return dataList; } - private void UpdatePlaylistData() + private string GetTrackCountForPlaylist(int playlistId) { - listViewModel.Clear(); - List dataList = GeneratePlaylistData(); - listViewModel.CreateData(dataList); + int trackCount = PlaylistManager.Instance.PlaylistTrackCount(playlistId); + return trackCount > 1 ? trackCount.ToString() + " tracks" : trackCount.ToString() + " track"; } private int UpdateLength(int length, int count) @@ -81,31 +125,5 @@ namespace MusicPlayer.ViewModels } return length; } - - private void OnPlaylistDataChanged(object sender, System.EventArgs e) - { - UpdatePlaylistData(); - } - - public string GetTrackCountForPlaylist(int playlistId) - { - int trackCount = PlaylistManager.Instance.PlaylistTrackCount(playlistId); - return trackCount > 1 ? trackCount.ToString() + " tracks" : trackCount.ToString() + " track"; - } - - public string NewPlayListName { get; set; } - - public bool CheckPlayListName(string playlistName) - { - Playlist playlist = PlaylistManager.Instance.GetPlaylist(playlistName); - if (playlist == null) - { - return true; - } - else - { - return false; - } - } } } diff --git a/music-player/ViewModels/SelectorViewModel.cs b/music-player/ViewModels/SelectorViewModel.cs index 8433f72..3e91a0c 100755 --- a/music-player/ViewModels/SelectorViewModel.cs +++ b/music-player/ViewModels/SelectorViewModel.cs @@ -41,9 +41,9 @@ namespace MusicPlayer.ViewModels return tracksShared; } - public PlaylistSelectorViewModel GetPlaylistSelectorViewModel() + public PlaylistSelectorViewModel GetPlaylistSelectorViewModel(List addedTrackList) { - return playlistSelectorViewModel ?? new PlaylistSelectorViewModel(); + return playlistSelectorViewModel ?? new PlaylistSelectorViewModel(addedTrackList); } } } diff --git a/music-player/Views/PlayerView.cs b/music-player/Views/PlayerView.cs index b66ae8b..e08fe96 100755 --- a/music-player/Views/PlayerView.cs +++ b/music-player/Views/PlayerView.cs @@ -61,6 +61,7 @@ namespace MusicPlayer.Views private PlayerViewModel viewModel; private PlayerViewState viewState; + private bool isPlaylistAddViewCreated = false; public PlayerView(PlayerViewModel viewModel) : base() { @@ -761,6 +762,10 @@ namespace MusicPlayer.Views ThemeChangeSensitive = true, }; actionButtonView.Add(playlistButton); + playlistButton.Clicked += (object o, ClickedEventArgs e) => + { + OnPlaylistAdd(); + }; favouriteButton = new MultiStateButton() { @@ -819,6 +824,27 @@ namespace MusicPlayer.Views }; } + private void OnPlaylistAdd() + { + if(isPlaylistAddViewCreated) + { + Tizen.Log.Info(AppConstants.LogTag, "Selector view is already created"); + return; + } + PlaylistSelectorViewModel playlistselectorviewModel = viewModel.GetPlaylistSelectorViewModel(); + if(playlistselectorviewModel == null) + { + Tizen.Log.Error(AppConstants.LogTag, "PlaylistSelectorViewModel is null"); + return; + } + PlaylistSelectorView selectorView = new PlaylistSelectorView(playlistselectorviewModel); + isPlaylistAddViewCreated = true; + selectorView.PlaylistMemberAdd += (object o, PlaylistMemberAddEventArgs e) => + { + isPlaylistAddViewCreated = false; + }; + } + private void AddThumbnail() { thumb = new ImageView() diff --git a/music-player/Views/PlaylistSelectorView.cs b/music-player/Views/PlaylistSelectorView.cs index 9b3c64f..e223281 100755 --- a/music-player/Views/PlaylistSelectorView.cs +++ b/music-player/Views/PlaylistSelectorView.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Tizen.Content.MediaContent; using MusicPlayer.ViewModels; using Tizen.NUI.Components; @@ -11,6 +12,16 @@ using MusicPlayer.Core; namespace MusicPlayer.Views { + class PlaylistMemberAddEventArgs: EventArgs + { + public PlaylistMemberAddEventArgs(PlaylistMemberAddStatus currentAddStatus) + { + PlaylistAddStatus = currentAddStatus; + } + + public PlaylistMemberAddStatus PlaylistAddStatus { get; private set; } + } + class PlaylistSelectorView : View { private View selectPlaylistContentArea; @@ -29,6 +40,8 @@ namespace MusicPlayer.Views private Button crossButton; private PlaylistSelectorViewModel viewModel; + public event EventHandler PlaylistMemberAdd; + public PlaylistSelectorView(PlaylistSelectorViewModel viewModel) { this.viewModel = viewModel; @@ -102,7 +115,7 @@ namespace MusicPlayer.Views WidthSpecification = LayoutParamPolicies.MatchParent, HeightSpecification = 1, BackgroundColor = UIColors.ItemSeperator, - Margin = new Extents(44, 44, 0, 0), + Margin = new Extents(64, 64, 0, 0), }; selectPlaylistContentArea.Add(itemSeperator); createNewPlaylistButton.Clicked += CreateNewPlaylistButtonClicked; @@ -143,12 +156,43 @@ namespace MusicPlayer.Views collectionView.ItemTemplate = new DataTemplate(() => { DefaultLinearItem layout = new DefaultLinearItem(); + layout.WidthSpecification = LayoutParamPolicies.MatchParent; + layout.HeightSpecification = 108; + layout.Seperator.Padding = new Extents(0, 0, 0, 0); + layout.Seperator.Margin = new Extents(0, 0, 0, 0); + layout.Seperator.WidthSpecification = LayoutParamPolicies.MatchParent; layout.Label.SetBinding(TextLabel.TextProperty, "PlaylistName"); layout.Padding = new Extents(0, 0, 0, 0); layout.Margin = new Extents(0, 0, 0, 0); return layout; }); collectionView.ItemsSource = viewModel.ListViewModel; + collectionView.BindingContext = viewModel; + collectionView.SetBinding(CollectionView.SelectedItemProperty, "PlaylistSelectedItem"); + collectionView.SelectionChanged += OnSelectionChange; + } + + private void OnSelectionChange(object sender, SelectionChangedEventArgs e) + { + CollectionView collectionView = (CollectionView)sender; + object item = collectionView.SelectedItem; + if(item == null) + { + Tizen.Log.Error(AppConstants.LogTag, "Selected item is null"); + return; + } + bool isAdded = viewModel.AddTracksToPlaylist(item); + if(isAdded == false) + { + Tizen.Log.Error(AppConstants.LogTag, "Failed to add track to playlist"); + } + if(createPlaylistDialog != null && createPlaylistDialog.IsOnWindow) + { + RemoveTheCreatePopup(); + } + PlaylistMemberAdd?.Invoke(this, new PlaylistMemberAddEventArgs(PlaylistMemberAddStatus.Added)); + RemoveTheSelectPopup(); + DeleteSelectorView(); } private void AddNoListText() @@ -181,7 +225,9 @@ namespace MusicPlayer.Views private void SelectPlaylistCancelButtonClicked(object sender, ClickedEventArgs e) { + PlaylistMemberAdd?.Invoke(this, new PlaylistMemberAddEventArgs(PlaylistMemberAddStatus.Cancelled)); RemoveTheSelectPopup(); + DeleteSelectorView(); } private void AddCreatePlaylistContentArea() @@ -266,7 +312,10 @@ namespace MusicPlayer.Views ThemeChangeSensitive = true, Position2D = new Position2D(976, 6), }; - crossButton.Clicked += CrossButtonClicked; + crossButton.Clicked += (object o, ClickedEventArgs e) => + { + textField.Text = string.Empty; + }; inputArea.Add(textField); inputArea.Add(crossButton); @@ -292,17 +341,12 @@ namespace MusicPlayer.Views } if (searchText.Length > 64) { - Notification.MakeToast("Maximum number of characters reached.", Notification.ToastCenter).Post(Notification.ToastShort); + ShowInfoMessage("Maximum number of characters reached"); underText.Text = "Can't enter more than 64 characters."; textField.Text = searchText.Substring(0, 63); } } - private void CrossButtonClicked(object sender, ClickedEventArgs e) - { - textField.Text = ""; - } - private void AddCreatePlaylistButtons() { createPlaylistCancelButton = new Button("CancelButton") @@ -325,25 +369,59 @@ namespace MusicPlayer.Views private void CreatePlaylistCancelButtonClicked(object sender, ClickedEventArgs e) { RemoveTheCreatePopup(); + DeleteTheCreatePopup(); + ShowTheSelectPopup(); + } + + private void ShowInfoMessage(string message) + { + Notification.MakeToast(message, Notification.ToastCenter).Post(Notification.ToastShort); } private void CreatePlaylistCreateButtonClicked(object sender, ClickedEventArgs e) { - if (viewModel.CheckPlayListName(textField.Text)) + if(string.IsNullOrEmpty(textField.Text) || string.IsNullOrWhiteSpace(textField.Text)) { - RemoveTheCreatePopup(); - Window.Instance.Add(selectPlaylistDialog); - Playlist playlist = PlaylistManager.Instance.AddPlaylist(textField.Text); - PlaylistModel playlistModel = new PlaylistModel(new PlaylistData(playlist.Id, playlist.Name, viewModel.GetTrackCountForPlaylist(playlist.Id), playlist.ThumbnailPath)); - collectionView.SelectedItem = playlistModel; + ShowInfoMessage("Can't create playlist with empty or whitespace only characters"); + return; } - else + if (viewModel.CreatePlaylist(textField.Text) == false) { - Notification.MakeToast("Playlist name already in use.", Notification.ToastCenter).Post(Notification.ToastShort); + ShowInfoMessage("Playlist name already in use."); underText.Text = "Playlist name already in use."; } } + private void DeleteTheCreatePopup() + { + inputArea?.Remove(textField); + textField?.Dispose(); + textField = null; + inputArea?.Remove(crossButton); + crossButton?.Dispose(); + crossButton = null; + + if (createPlaylistContentArea != null) + { + List children = createPlaylistContentArea.Children; + while (children.Count > 0) + { + View child = children[0]; + createPlaylistContentArea.Remove(child); + child?.Dispose(); + } + } + inputArea = null; + underText = null; + createPlaylistDialog?.Dispose(); + createPlaylistDialog = null; + createPlaylistContentArea = null; + createPlaylistCancelButton?.Dispose(); + createPlaylistCancelButton = null; + createPlaylistCreateButton?.Dispose(); + createPlaylistCreateButton = null; + } + protected override void Dispose(DisposeTypes type) { if (Disposed) @@ -352,13 +430,7 @@ namespace MusicPlayer.Views } if (type == DisposeTypes.Explicit) { - inputArea?.Remove(textField); - textField?.Dispose(); - textField = null; - inputArea?.Remove(crossButton); - crossButton?.Dispose(); - crossButton = null; - + DeleteTheCreatePopup(); if (selectPlaylistContentArea != null) { List children = selectPlaylistContentArea.Children; @@ -369,56 +441,42 @@ namespace MusicPlayer.Views child?.Dispose(); } } - if (createPlaylistContentArea != null) - { - List children = createPlaylistContentArea.Children; - while (children.Count > 0) - { - View child = children[0]; - createPlaylistContentArea.Remove(child); - child?.Dispose(); - } - } + createNewPlaylistButton = null; collectionView = null; noListText = null; - inputArea = null; - underText = null; selectPlaylistDialog?.Dispose(); selectPlaylistDialog = null; - createPlaylistDialog?.Dispose(); - createPlaylistDialog = null; selectPlaylistContentArea = null; - createPlaylistContentArea = null; selectPlaylistCancelButton?.Dispose(); selectPlaylistCancelButton = null; - createPlaylistCancelButton?.Dispose(); - createPlaylistCancelButton = null; - createPlaylistCreateButton?.Dispose(); - createPlaylistCreateButton = null; } base.Dispose(type); } - public void DeleteSelectorView() + private void DeleteSelectorView() { Dispose(DisposeTypes.Explicit); } - public CollectionView GetCollectionView() + + private void RemoveTheSelectPopup() { - return collectionView; + Window.Instance.Remove(selectPlaylistDialog); } - public void RemoveTheSelectPopup() + private void ShowTheSelectPopup() { - Window.Instance.Remove(selectPlaylistDialog); + if(selectPlaylistDialog != null) + { + Window.Instance.Add(selectPlaylistDialog); + } } - public void RemoveTheCreatePopup() + private void RemoveTheCreatePopup() { Window.Instance.Remove(createPlaylistDialog); } diff --git a/music-player/Views/PlaylistView.cs b/music-player/Views/PlaylistView.cs index 6ad637a..7058165 100755 --- a/music-player/Views/PlaylistView.cs +++ b/music-player/Views/PlaylistView.cs @@ -218,7 +218,7 @@ namespace MusicPlayer.Views Button createButton = new Button() { Name = "AlertDialogCreateButton", - Text = "Allow", + Text = "Create", }; return createButton; } diff --git a/music-player/Views/SelectorView.cs b/music-player/Views/SelectorView.cs index 86b7737..42b645c 100755 --- a/music-player/Views/SelectorView.cs +++ b/music-player/Views/SelectorView.cs @@ -183,27 +183,15 @@ namespace MusicPlayer.Views } else if (currentViewType == OperationViewType.AddToPlaylist) { - PlaylistSelectorViewModel playlistSelectorViewModel = viewModel.GetPlaylistSelectorViewModel(); + PlaylistSelectorViewModel playlistSelectorViewModel = viewModel.GetPlaylistSelectorViewModel(SelectedItemList); PlaylistSelectorView playlistSelectorView = new PlaylistSelectorView(playlistSelectorViewModel); - if (playlistSelectorView.GetCollectionView() != null) + playlistSelectorView.PlaylistMemberAdd += (object o, PlaylistMemberAddEventArgs e) => { - playlistSelectorView.GetCollectionView().SelectionChanged += (object sender, SelectionChangedEventArgs e) => + if (e.PlaylistAddStatus == PlaylistMemberAddStatus.Added) { - object item = playlistSelectorView.GetCollectionView().SelectedItem; - PlaylistModel playlist; - if (item is PlaylistModel) - { - playlist = (PlaylistModel)item; - bool additionSuccessful = PlaylistManager.Instance.AddTracks(playlist.PlaylistId, SelectedItemList); - if (additionSuccessful == true) - { - playlistSelectorView.RemoveTheSelectPopup(); - playlistSelectorView.DeleteSelectorView(); - ClearSelectionAndRemove(); - } - } - }; - } + ClearSelectionAndRemove(); + } + }; } } diff --git a/packaging/org.tizen.MusicPlayer-1.0.0.tpk b/packaging/org.tizen.MusicPlayer-1.0.0.tpk index 8783c74..000ef08 100755 Binary files a/packaging/org.tizen.MusicPlayer-1.0.0.tpk and b/packaging/org.tizen.MusicPlayer-1.0.0.tpk differ