using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using FluentAvalonia.UI.Media.Animation;
using FluentAvalonia.UI.Navigation;
using System.Reflection;
using Toolkit.Foundation;
using Toolkit.UI.Controls.Avalonia;
namespace Toolkit.Avalonia;
public class FrameHandler(INavigationContext navigationContext) :
INavigateHandler,
INavigateBackHandler
{
public Task Handle(Navigate args,
CancellationToken cancellationToken)
{
if (args.Context is Frame frame)
{
frame.NavigationPageFactory ??= new NavigationPageFactory();
if (args.Template is Control control)
{
void NavigatingFrom(object? sender,
Control control)
{
async void HandleNavigatingFrom(object? _,
NavigatingCancelEventArgs args)
{
Dictionary results = [];
control.RemoveHandler(Frame.NavigatingFromEvent, HandleNavigatingFrom);
NavigatedFrom(sender, control, () => results);
if (control.DataContext is object content)
{
if (content is IConfirmation confirmation &&
!await confirmation.Confirm())
{
args.Cancel = true;
}
if (!args.Cancel)
{
if (content is IDeactivating deactivating)
{
await deactivating.Deactivating();
}
Type contentType = content.GetType();
if (contentType.GetInterfaces() is Type[] contracts)
{
foreach (Type contract in contracts)
{
if (contract.Name == typeof(IDeactivating<>).Name &&
contract.GetGenericArguments() is { Length: 1 } arguments)
{
if (contentType.GetMethods().FirstOrDefault(x =>
x.Name == "Deactivating" && x.ReturnType == typeof(Task<>)
.MakeGenericType(arguments[0]))
is MethodInfo methodInfo)
{
if (methodInfo.GetCustomAttribute()
is NavigationContextAttribute attribute)
{
if (await methodInfo.InvokeAsync