using CommunityToolkit.Diagnostics;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using OwlCore.Extensions;
using StrixMusic.Sdk.Services;
using StrixMusic.Sdk.ViewModels;
using StrixMusic.Sdk.WinUI.Controls.Shells;
using StrixMusic.Sdk.WinUI.Services.Localization;
using StrixMusic.Sdk.WinUI.Services.ShellManagement;
using StrixMusic.Shells.Groove.Helper;
using StrixMusic.Shells.Groove.Messages.Navigation.Pages;
using StrixMusic.Shells.Groove.Messages.Navigation.Pages.Abstract;
using StrixMusic.Shells.Groove.ViewModels.Collections;
using Windows.ApplicationModel.Core;
using Windows.UI;
using Windows.UI.Core;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
namespace StrixMusic.Shells.Groove
{
public sealed partial class GrooveShell : Shell
{
///
/// A backing for the property.
///
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register(nameof(Title), typeof(string), typeof(GrooveShell), new PropertyMetadata(null));
///
/// A backing for the property.
///
public static readonly DependencyProperty ShowLargeHeaderProperty =
DependencyProperty.Register(nameof(ShowLargeHeader), typeof(bool), typeof(GrooveShell), new PropertyMetadata(true));
///
/// A backing for the property.
///
public static readonly DependencyProperty PlaylistCollectionViewModelProperty =
DependencyProperty.Register(nameof(PlaylistCollectionViewModel), typeof(GroovePlaylistCollectionViewModel), typeof(GrooveShell), new PropertyMetadata(null));
private LocalizationResourceLoader _localizationService;
///
/// Initializes a new instance of the class.
///
public GrooveShell(StrixDataRootViewModel dataRootViewModel)
: base(dataRootViewModel)
{
this.InitializeComponent();
// Register home page navigation
WeakReferenceMessenger.Default.Register(this, (s, e) => NavigatePage(e));
// Register album, artist, and playlist page navigation
WeakReferenceMessenger.Default.Register(this, (s, e) => NavigatePage(e));
WeakReferenceMessenger.Default.Register(this, (s, e) => NavigatePage(e));
WeakReferenceMessenger.Default.Register(this, (s, e) => NavigatePage(e));
// Register playlists page navigation
WeakReferenceMessenger.Default.Register(this, (s, e) => NavigatePage(e));
_localizationService = Ioc.Default.GetRequiredService();
HamburgerPressedCommand = new RelayCommand(HamburgerToggled);
RegisterPropertyChangedCallback(DataRootProperty, new DependencyPropertyChangedCallback((x, y) => x.Cast().OnDataRootChanged()));
Unloaded += GrooveShell_Unloaded;
Loaded += GrooveShell_Loaded;
}
///
/// Metadata used to identify this shell before instantiation.
///
public static ShellMetadata Metadata { get; }
= new ShellMetadata(id: "GrooveMusic.10.21061.10121.0",
displayName: "Groove Music",
description: "A faithful recreation of the Groove Music app from Windows 10");
private void GrooveShell_Loaded(object sender, RoutedEventArgs e)
{
Loaded -= GrooveShell_Loaded;
Guard.IsNotNull(DataRoot, nameof(DataRoot));
Notifications.IsHandled = true;
NavigationTracker.Instance.Initialize();
OnDataRootChanged();
}
private void GrooveShell_Unloaded(object sender, RoutedEventArgs e)
{
Unloaded -= GrooveShell_Unloaded;
WeakReferenceMessenger.Default.Reset();
}
private void OnDataRootChanged()
{
if (DataRoot is null)
return;
PlaylistCollectionViewModel = new GroovePlaylistCollectionViewModel
{
PlaylistCollection = (LibraryViewModel)DataRoot.Library
};
if (DataRoot?.Library != null)
{
Bindings.Update();
_ = WeakReferenceMessenger.Default.Send(new HomeViewNavigationRequestMessage((LibraryViewModel)DataRoot.Library));
}
}
///
/// Gets or sets the Title text for the Groove Shell.
///
public bool ShowLargeHeader
{
get { return (bool)GetValue(ShowLargeHeaderProperty); }
set { SetValue(ShowLargeHeaderProperty, value); }
}
///
/// Gets or sets the Title text for the Groove Shell.
///
public string Title
{
get => (string)GetValue(TitleProperty);
set => SetValue(TitleProperty, value);
}
///
/// The for the on display in the pane.
///
public GroovePlaylistCollectionViewModel? PlaylistCollectionViewModel
{
get => (GroovePlaylistCollectionViewModel?)GetValue(PlaylistCollectionViewModelProperty);
set => SetValue(PlaylistCollectionViewModelProperty, value);
}
///
/// Gets a Command that handles a Hamburger button press.
///
public RelayCommand HamburgerPressedCommand { get; }
///
protected override void SetupTitleBar()
{
base.SetupTitleBar();
#if NETFX_CORE
CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
ApplicationViewTitleBar titleBar = ApplicationView.GetForCurrentView().TitleBar;
titleBar.ButtonForegroundColor = Colors.White;
titleBar.ButtonBackgroundColor = Colors.Transparent;
#endif
SystemNavigationManager currentView = SystemNavigationManager.GetForCurrentView();
currentView.AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
currentView.BackRequested += CurrentView_BackRequested;
}
private void CurrentView_BackRequested(object sender, BackRequestedEventArgs e)
{
NavigationTracker.Instance.NavigateBackwards();
}
private void NavigationButtonClicked(object sender, RoutedEventArgs e)
{
if (sender is ToggleButton button)
{
switch (button.Tag as string)
{
case "MyMusic":
Guard.IsNotNull(DataRoot?.Library, nameof(DataRoot.Library));
WeakReferenceMessenger.Default.Send(new HomeViewNavigationRequestMessage((LibraryViewModel)DataRoot.Library));
break;
case "Playlists":
Guard.IsNotNull(DataRoot?.Library, nameof(DataRoot.Library));
WeakReferenceMessenger.Default.Send(new PlaylistsViewNavigationRequestMessage((LibraryViewModel)DataRoot.Library));
break;
}
}
}
private void HamburgerToggled()
{
MainSplitView.IsPaneOpen = !MainSplitView.IsPaneOpen;
}
private void OnPaneStateChanged(SplitView sender, object e) => UpdatePaneState();
private void UpdatePaneState()
{
if (MainSplitView.IsPaneOpen)
VisualStateManager.GoToState(this, "Full", true);
else
VisualStateManager.GoToState(this, "Compact", true);
}
private void NavigatePage(PageNavigationRequestMessage viewModel)
{
MainContent.Content = viewModel.PageData;
if (viewModel is PlaylistsViewNavigationRequestMessage playlistsNavReq)
{
if (Resources.TryGetValue("GroovePlaylistsPageDataTemplate", out var dataTemplate))
MainContent.ContentTemplate = (DataTemplate)dataTemplate;
else
Ioc.Default.GetRequiredService().RaiseNotification("Error", "Unable to show page.");
}
Guard.IsNotNull(_localizationService, nameof(_localizationService));
Title = _localizationService.Music?.GetString(viewModel.PageTitleResource) ?? viewModel.PageTitleResource;
ShowLargeHeader = viewModel.ShowLargeHeader;
UpdateSelectedNavigationButton(viewModel);
}
private void UpdateSelectedNavigationButton(PageNavigationRequestMessage viewModel)
{
ToggleButton? button = viewModel switch
{
HomeViewNavigationRequestMessage _ => MyMusicButton,
PlaylistViewNavigationRequestMessage _ => PlaylistsButton,
_ => null,
};
// Reset all buttons, but not the PlaylistList
MyMusicButton.IsChecked = false;
RecentButton.IsChecked = false;
NowPlayingButton.IsChecked = false;
PlaylistsButton.IsChecked = false;
if (button != null)
{
PlaylistList.ClearSelected();
// Set the active navigation button
button.IsChecked = true;
}
}
}
}