using System;
using System.Collections.Generic;
using CommunityToolkit.Diagnostics;
using CommunityToolkit.Mvvm.DependencyInjection;
using StrixMusic.Sdk.Services.Navigation;
using StrixMusic.Sdk.ViewModels;
using StrixMusic.Sdk.WinUI.Controls.Shells;
using StrixMusic.Sdk.WinUI.Controls.Views;
using StrixMusic.Sdk.WinUI.Services.ShellManagement;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace StrixMusic.Shells.Default
{
///
/// An empty page that can be used on its own or navigated to within a Frame.
///
public sealed partial class DefaultShell : Shell
{
private readonly IReadOnlyDictionary _pagesMapping;
private readonly Stack _history = new Stack();
private INavigationService _navigationService;
///
/// Initializes a new instance of the class.
///
public DefaultShell(StrixDataRootViewModel dataRootViewModel)
: base(dataRootViewModel)
{
InitializeComponent();
// Initialize map between NavigationItems and page types
_pagesMapping = new Dictionary
{
{ HomeItem, typeof(HomeView) },
{ NowPlayingItem, typeof(NowPlayingView) },
};
_navigationService = SetupNavigationService();
}
///
/// Metadata used to identify this shell before instantiation.
///
public static ShellMetadata Metadata { get; } =
new(id: "default.sandbox",
displayName: "Sandbox",
description: "Used by devs to test and create default controls for other shells.");
private INavigationService SetupNavigationService()
{
var navigationService = Ioc.Default.GetRequiredService>();
navigationService.NavigationRequested += NavigationService_NavigationRequested;
navigationService.BackRequested += Shell_BackRequested;
navigationService.RegisterCommonPage(typeof(HomeView));
navigationService.RegisterCommonPage(typeof(NowPlayingView));
return navigationService;
}
///
protected override void SetupTitleBar()
{
Guard.IsNotNull(_navigationService, nameof(_navigationService));
base.SetupTitleBar();
SystemNavigationManager currentView = SystemNavigationManager.GetForCurrentView();
currentView.AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
currentView.BackRequested += (s, e) => _navigationService.GoBack();
}
private void NavigationService_NavigationRequested(object sender, NavigateEventArgs e)
{
if (!e.IsOverlay)
{
_history.Push((Control)MainContent.Content);
MainContent.Content = e.Page;
}
else
{
OverlayContent.Content = e.Page;
OverlayContent.Visibility = Visibility.Visible;
// No sense checking the NavigationItems if the type is an overlay
return;
}
// Set the selected NavigationItem to the new page, if it's on the list
Type controlType = e.Page.GetType();
bool containsValue = controlType == typeof(SettingsView);
// This isn't great, but there should only be 4 items
foreach (var value in _pagesMapping.Values)
{
containsValue = containsValue || (value == controlType);
}
if (!containsValue)
{
NavView.SelectedItem = null;
}
else
{
// If it's a top level item, clear history
_history.Clear();
}
}
private void Shell_BackRequested(object sender, EventArgs e)
{
if (OverlayContent.Visibility == Visibility.Visible)
{
OverlayContent.Visibility = Visibility.Collapsed;
return;
}
if (_history.Count > 0)
{
MainContent.Content = _history.Pop();
}
}
private void AutoSuggestBox_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
{
Guard.IsNotNull(_navigationService, nameof(_navigationService));
_navigationService.NavigateTo(typeof(SearchView), false, args.QueryText);
}
private void NavView_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
{
Guard.IsNotNull(_navigationService, nameof(_navigationService));
if (args.IsSettingsInvoked)
{
_navigationService.NavigateTo(typeof(SettingsView));
return;
}
NavigationViewItemBase invokedItem = (args.InvokedItemContainer as NavigationViewItemBase)!;
if (invokedItem == null || !_pagesMapping.ContainsKey(invokedItem))
{
return;
}
_navigationService.NavigateTo(_pagesMapping[invokedItem], invokedItem == NowPlayingItem);
}
}
}