2019-05-17 22:21:02 +00:00
|
|
|
|
using System;
|
2019-05-24 14:27:19 +00:00
|
|
|
|
using System.Collections.ObjectModel;
|
2019-07-15 19:03:59 +00:00
|
|
|
|
using System.Collections.Generic;
|
2019-12-07 18:47:45 +00:00
|
|
|
|
using System.Threading.Tasks;
|
2019-05-24 14:27:19 +00:00
|
|
|
|
using System.Linq;
|
2019-07-05 18:17:09 +00:00
|
|
|
|
using Aurora.Design.Components.NavigationMenu;
|
|
|
|
|
using Aurora.Design.Views.MainView;
|
2019-05-17 22:21:02 +00:00
|
|
|
|
using Xamarin.Forms;
|
|
|
|
|
using Xamarin.Forms.Xaml;
|
2019-11-07 03:32:43 +00:00
|
|
|
|
using Aurora.Models.Media;
|
|
|
|
|
using Aurora.Design.Components.MediaPlayer;
|
2019-12-05 04:42:23 +00:00
|
|
|
|
using Aurora.Services.PlayerService;
|
2019-12-07 18:47:45 +00:00
|
|
|
|
using System.Threading;
|
2019-05-17 22:21:02 +00:00
|
|
|
|
|
2019-07-05 18:17:09 +00:00
|
|
|
|
namespace Aurora.Design.Views.Main
|
2019-05-24 14:27:19 +00:00
|
|
|
|
{
|
2019-12-05 04:42:23 +00:00
|
|
|
|
public enum PlayAction
|
|
|
|
|
{
|
|
|
|
|
Play,
|
|
|
|
|
Pause,
|
|
|
|
|
Resume,
|
|
|
|
|
Stop
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-09 00:54:51 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Delegate for updating player metadata
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="media"></param>
|
2019-12-07 18:47:45 +00:00
|
|
|
|
public delegate Task SetPlayerDelegate(BaseMedia media, PlayAction action);
|
2019-12-05 04:42:23 +00:00
|
|
|
|
public delegate bool GetIsPlayingDelegate();
|
2019-12-19 03:32:08 +00:00
|
|
|
|
public delegate void ShowModalDelegate(Type view, BaseDialogViewModel viewModel);
|
|
|
|
|
public delegate void HideModalDelegate();
|
2019-12-07 18:47:45 +00:00
|
|
|
|
public delegate void FinishDialogDelegate();
|
2019-11-09 19:55:09 +00:00
|
|
|
|
|
2019-05-17 22:21:02 +00:00
|
|
|
|
[XamlCompilation(XamlCompilationOptions.Compile)]
|
2019-11-30 19:41:36 +00:00
|
|
|
|
public partial class MainView : ContentPage//, IDisposable
|
2019-05-17 22:21:02 +00:00
|
|
|
|
{
|
2019-07-15 19:03:59 +00:00
|
|
|
|
private Dictionary<int, BaseViewModel> _viewModels;
|
|
|
|
|
private BaseViewModel _lastViewModel;
|
2019-12-05 04:42:23 +00:00
|
|
|
|
private Player _playerComponent;
|
|
|
|
|
private PlayerService _playerService;
|
2019-11-09 19:55:09 +00:00
|
|
|
|
private ContentPresenter _viewContent;
|
2019-07-15 19:03:59 +00:00
|
|
|
|
|
2019-05-17 22:21:02 +00:00
|
|
|
|
public MainView()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
2019-05-18 21:25:36 +00:00
|
|
|
|
BindingContext = new MainViewModel();
|
2019-07-15 19:03:59 +00:00
|
|
|
|
_viewModels = new Dictionary<int, BaseViewModel>();
|
2019-11-09 19:55:09 +00:00
|
|
|
|
|
2019-12-05 04:42:23 +00:00
|
|
|
|
_playerComponent = Player;
|
2019-12-07 18:47:45 +00:00
|
|
|
|
|
2019-12-10 20:10:27 +00:00
|
|
|
|
_viewContent = (ContentPresenter)Content.FindByName("ViewContent");
|
2019-12-05 04:42:23 +00:00
|
|
|
|
_playerService = PlayerService.Instance;
|
2019-11-09 19:55:09 +00:00
|
|
|
|
|
2019-11-07 03:32:43 +00:00
|
|
|
|
MasterPage.ListView.ItemSelected += OnNavItemSelected;
|
2019-05-24 14:27:19 +00:00
|
|
|
|
|
2019-05-24 19:59:26 +00:00
|
|
|
|
Appearing += OnAppearing;
|
|
|
|
|
}
|
2019-11-09 00:54:51 +00:00
|
|
|
|
|
|
|
|
|
public void Dispose()
|
2019-05-24 19:59:26 +00:00
|
|
|
|
{
|
|
|
|
|
Appearing -= OnAppearing;
|
2019-05-17 22:21:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-11-09 00:54:51 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Event handler for side bar items being selected
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="sender"></param>
|
|
|
|
|
/// <param name="e"></param>
|
2019-11-07 03:32:43 +00:00
|
|
|
|
private void OnNavItemSelected(object sender, SelectedItemChangedEventArgs e)
|
2019-05-17 22:21:02 +00:00
|
|
|
|
{
|
|
|
|
|
var item = e.SelectedItem as NavigationItem;
|
|
|
|
|
if (item == null)
|
|
|
|
|
return;
|
|
|
|
|
|
2019-05-24 14:27:19 +00:00
|
|
|
|
var view = (View)Activator.CreateInstance(item.TargetType);
|
2019-05-17 22:21:02 +00:00
|
|
|
|
|
2019-07-15 19:03:59 +00:00
|
|
|
|
//Check if we have an instantiated viewModel
|
|
|
|
|
BaseViewModel vm = new BaseViewModel();
|
|
|
|
|
if (_viewModels.ContainsKey(item.Id))
|
|
|
|
|
{
|
|
|
|
|
_viewModels.TryGetValue(item.Id, out vm);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (item.TargetViewModelType.BaseType != typeof(BaseViewModel))
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException("TargetViewModel field must be of type BaseViewModel");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Instantiate new view model
|
|
|
|
|
vm = (BaseViewModel)Activator.CreateInstance(item.TargetViewModelType);
|
|
|
|
|
_viewModels.Add(item.Id, vm);
|
2019-11-07 03:32:43 +00:00
|
|
|
|
|
2019-11-09 00:54:51 +00:00
|
|
|
|
}
|
2019-11-07 03:32:43 +00:00
|
|
|
|
|
2019-12-07 18:47:45 +00:00
|
|
|
|
//Assign player controls to viewmodel
|
|
|
|
|
AssignPlayerControls(vm);
|
|
|
|
|
ChangeModalVisiblity(false);
|
|
|
|
|
|
2019-07-15 19:03:59 +00:00
|
|
|
|
//Activate viewmodel
|
|
|
|
|
vm.OnActive();
|
|
|
|
|
|
|
|
|
|
//Deactivate last viewModel
|
|
|
|
|
_lastViewModel.OnInactive();
|
2019-11-09 00:54:51 +00:00
|
|
|
|
//Unasign deactivating vm
|
|
|
|
|
UnassignPlayerControls(_lastViewModel);
|
2019-07-15 19:03:59 +00:00
|
|
|
|
|
|
|
|
|
//Assign viewModel
|
|
|
|
|
_lastViewModel = vm;
|
|
|
|
|
view.BindingContext = vm;
|
|
|
|
|
|
2019-11-09 19:55:09 +00:00
|
|
|
|
_viewContent.Content = view;
|
2019-05-17 22:21:02 +00:00
|
|
|
|
}
|
2019-05-24 19:59:26 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Event handler for page appearing.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="sender">The object that fired the event.</param>
|
|
|
|
|
/// <param name="args">The event arguments</param>
|
|
|
|
|
private void OnAppearing(object sender, EventArgs args)
|
|
|
|
|
{
|
|
|
|
|
//Set initial view from first item in list
|
|
|
|
|
ObservableCollection<NavigationGroupItem> screenList = (ObservableCollection<NavigationGroupItem>)MasterPage.ListView.ItemsSource;
|
2019-07-15 19:03:59 +00:00
|
|
|
|
|
|
|
|
|
//Assign viewModel
|
|
|
|
|
NavigationItem firstNavItem = screenList.FirstOrDefault().FirstOrDefault();
|
|
|
|
|
var view = (View)Activator.CreateInstance(firstNavItem.TargetType);
|
|
|
|
|
|
|
|
|
|
BaseViewModel vm = new BaseViewModel();
|
|
|
|
|
if (_viewModels.ContainsKey(firstNavItem.Id))
|
|
|
|
|
{
|
|
|
|
|
_viewModels.TryGetValue(firstNavItem.Id, out vm);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//Instantiate new view model
|
|
|
|
|
vm = (BaseViewModel)Activator.CreateInstance(firstNavItem.TargetViewModelType);
|
|
|
|
|
_viewModels.Add(firstNavItem.Id, vm);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
view.BindingContext = vm;
|
|
|
|
|
_lastViewModel = vm;
|
2019-11-09 00:54:51 +00:00
|
|
|
|
AssignPlayerControls(vm);
|
2019-12-07 18:47:45 +00:00
|
|
|
|
ChangeModalVisiblity(false);
|
2019-07-15 19:03:59 +00:00
|
|
|
|
vm.OnActive();
|
2019-05-24 19:59:26 +00:00
|
|
|
|
|
2019-11-09 19:55:09 +00:00
|
|
|
|
_viewContent.Content = view;
|
2019-12-02 04:20:55 +00:00
|
|
|
|
MasterPage.ListView.SelectedItem = firstNavItem;
|
2019-05-24 19:59:26 +00:00
|
|
|
|
|
|
|
|
|
}
|
2019-11-07 03:32:43 +00:00
|
|
|
|
|
2019-11-09 00:54:51 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Unassign setplayer delegate to prevent vms from changing player info when inactive
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="vm"></param>
|
|
|
|
|
private void UnassignPlayerControls(BaseViewModel vm)
|
|
|
|
|
{
|
2019-12-05 04:42:23 +00:00
|
|
|
|
vm.ChangePlayerState = null;
|
|
|
|
|
vm.IsPlaying = null;
|
2019-12-07 18:47:45 +00:00
|
|
|
|
vm.ShowModal = null;
|
2019-11-09 00:54:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Assign main views music player controls to a view model
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="vm">BaseViewModel to assign controls to</param>
|
|
|
|
|
private void AssignPlayerControls(BaseViewModel vm)
|
|
|
|
|
{
|
2019-12-05 04:42:23 +00:00
|
|
|
|
_playerComponent.PlayButtonCommand = new Command(vm.OnPlayButtonExecute, vm.CanPlayButtonExecute);
|
|
|
|
|
_playerComponent.NextButtonCommand = new Command(vm.OnNextButtonExecute, vm.CanNextButtonExecute);
|
|
|
|
|
_playerComponent.PreviousButtonCommand = new Command(vm.OnPreviousButtonExecute, vm.CanPreviousButtonExecute);
|
2019-11-09 00:54:51 +00:00
|
|
|
|
|
2019-12-05 04:42:23 +00:00
|
|
|
|
vm.ChangePlayerState = ChangePlayerState;
|
|
|
|
|
vm.IsPlaying = () =>
|
|
|
|
|
{
|
|
|
|
|
return _playerService.PlaybackState == PlaybackState.Playing;
|
|
|
|
|
};
|
2019-12-19 03:32:08 +00:00
|
|
|
|
vm.ShowModal = this.ShowModal;
|
|
|
|
|
vm.HideModal = this.HideModal;
|
2019-12-07 18:47:45 +00:00
|
|
|
|
|
2019-11-09 00:54:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-11-09 19:55:09 +00:00
|
|
|
|
/// <summary>
|
2019-12-05 04:42:23 +00:00
|
|
|
|
/// Delegate handler for a view model controling music playback
|
2019-11-09 19:55:09 +00:00
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="media"></param>
|
2019-12-05 04:42:23 +00:00
|
|
|
|
/// <param name="action"></param>
|
|
|
|
|
/// <returns></returns>
|
2019-12-07 18:47:45 +00:00
|
|
|
|
private async Task ChangePlayerState(BaseMedia media, PlayAction action)
|
2019-11-09 00:54:51 +00:00
|
|
|
|
{
|
2019-12-05 04:42:23 +00:00
|
|
|
|
if (media != null && media.Metadata is AudioMetadata)
|
2019-11-09 00:54:51 +00:00
|
|
|
|
{
|
|
|
|
|
AudioMetadata meta = (AudioMetadata)media.Metadata;
|
2019-12-05 04:42:23 +00:00
|
|
|
|
_playerComponent.ArtistName = meta.Artist;
|
|
|
|
|
_playerComponent.SongTitle = meta.Title;
|
2019-11-09 00:54:51 +00:00
|
|
|
|
}
|
2019-11-09 19:55:09 +00:00
|
|
|
|
|
2019-12-05 04:42:23 +00:00
|
|
|
|
switch (action)
|
|
|
|
|
{
|
|
|
|
|
case PlayAction.Pause:
|
|
|
|
|
{
|
|
|
|
|
_playerService.Pause();
|
|
|
|
|
_playerComponent.IsPlaying = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PlayAction.Play:
|
|
|
|
|
{
|
|
|
|
|
if (media == null)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!_playerService.IsMediaLoaded(media))
|
|
|
|
|
{
|
|
|
|
|
await _playerService.LoadMedia(media).ConfigureAwait(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_playerService.Play();
|
|
|
|
|
_playerComponent.IsPlaying = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PlayAction.Resume:
|
|
|
|
|
{
|
|
|
|
|
_playerService.Play();
|
|
|
|
|
_playerComponent.IsPlaying = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PlayAction.Stop:
|
|
|
|
|
{
|
|
|
|
|
_playerService.Stop();
|
|
|
|
|
_playerComponent.IsPlaying = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-12-04 22:53:49 +00:00
|
|
|
|
|
|
|
|
|
}
|
2019-12-07 18:47:45 +00:00
|
|
|
|
|
2019-12-19 03:32:08 +00:00
|
|
|
|
private void ShowModal(Type view, BaseDialogViewModel viewModel)
|
2019-12-07 18:47:45 +00:00
|
|
|
|
{
|
2019-12-19 03:32:08 +00:00
|
|
|
|
ContentPresenter modalContainer = (ContentPresenter)Modal.FindByName("ViewContent");
|
|
|
|
|
var vw = (View)Activator.CreateInstance(view);
|
2019-12-07 18:47:45 +00:00
|
|
|
|
|
2019-12-19 03:32:08 +00:00
|
|
|
|
vw.BindingContext = viewModel;
|
2019-12-07 18:47:45 +00:00
|
|
|
|
|
2019-12-19 03:32:08 +00:00
|
|
|
|
//Set modal container content
|
|
|
|
|
modalContainer.Content = vw;
|
2019-12-07 18:47:45 +00:00
|
|
|
|
|
2019-12-19 03:32:08 +00:00
|
|
|
|
//Set visibility
|
|
|
|
|
ChangeModalVisiblity(true);
|
|
|
|
|
}
|
2019-12-07 18:47:45 +00:00
|
|
|
|
|
2019-12-19 03:32:08 +00:00
|
|
|
|
private void HideModal()
|
|
|
|
|
{
|
|
|
|
|
ChangeModalVisiblity(false);
|
2019-12-07 18:47:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ChangeModalVisiblity(bool isVisible)
|
|
|
|
|
{
|
|
|
|
|
Modal.IsVisible = isVisible;
|
2019-12-19 03:32:08 +00:00
|
|
|
|
Content.IsVisible = !isVisible;
|
2019-12-07 18:47:45 +00:00
|
|
|
|
}
|
2019-05-17 22:21:02 +00:00
|
|
|
|
}
|
2019-12-05 04:42:23 +00:00
|
|
|
|
}
|