using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.JSInterop;
namespace AntDesign
{
///
/// create and open a Modal dialog
///
public partial class ModalService: IDisposable
{
internal event Func OnModalOpenEvent;
internal event Func OnModalCloseEvent;
internal event Func OnModalUpdateEvent;
private readonly NavigationManager _navigationManager;
private readonly IJSRuntime _jsRuntime;
internal static HashSet ReusedModals = new HashSet();
///
/// constructor
///
public ModalService(NavigationManager navigationManager, IJSRuntime jsRuntime)
{
_navigationManager = navigationManager;
_navigationManager.LocationChanged += NavigationManager_LocationChanged;
_jsRuntime = jsRuntime;
}
///
/// Destroy all reused Modal
///
///
///
private async void NavigationManager_LocationChanged(object sender, Microsoft.AspNetCore.Components.Routing.LocationChangedEventArgs e)
{
if (ReusedModals.Count > 0)
{
// Since Modal cannot be captured, it can only be removed through JS
await _jsRuntime.InvokeVoidAsync(JSInteropConstants.DestroyAllDialog);
ReusedModals.Clear();
}
}
///
/// Create and open a Modal
///
///
public Task CreateModalAsync(ModalOptions config)
{
if (config == null)
{
throw new ArgumentNullException(nameof(config));
}
ModalRef modalRef = new ModalRef(config, this);
config.ModalRef = modalRef;
return CreateOrOpenModalAsync(modalRef);
}
///
/// Create and open a Modal
///
///
public Task> CreateModalAsync(ModalOptions config)
{
if (config == null)
{
throw new ArgumentNullException(nameof(config));
}
var modalRef = new ModalRef(config, this);
config.ModalRef = modalRef;
return CreateOrOpenModalAsync(modalRef);
}
///
/// Create and open a Modal with template
///
///
///
///
///
///
public Task CreateModalAsync(ModalOptions config, TComponentOptions componentOptions) where TComponent : FeedbackComponent
{
if (config == null)
{
throw new ArgumentNullException(nameof(config));
}
ModalRef modalRef = new ModalRef(config, this);
void Child(RenderTreeBuilder builder)
{
builder.OpenComponent(0);
builder.AddAttribute(1, "FeedbackRef", modalRef);
builder.AddAttribute(2, "Options", componentOptions);
builder.CloseComponent();
}
config.Content = Child;
config.ModalRef = modalRef;
return CreateOrOpenModalAsync(modalRef);
}
///
/// Create and open a Modal with template
///
///
///
///
///
///
///
public Task> CreateModalAsync(ModalOptions config, TComponentOptions componentOptions) where TComponent : FeedbackComponent
{
if (config == null)
{
throw new ArgumentNullException(nameof(config));
}
var modalRef = new ModalRef(config, this);
void Child(RenderTreeBuilder builder)
{
builder.OpenComponent(0);
builder.AddAttribute(1, "FeedbackRef", modalRef);
builder.AddAttribute(2, "Options", componentOptions);
builder.CloseComponent();
}
config.Content = Child;
config.ModalRef = modalRef;
return CreateOrOpenModalAsync(modalRef);
}
///
/// create or open a Modal dialog
///
///
///
internal Task CreateOrOpenModalAsync(ModalRef modalRef)
{
OnModalOpenEvent?.Invoke(modalRef);
ReusedModals.Add(modalRef);
return Task.FromResult(modalRef);
}
///
/// create or open a Modal dialog
///
///
///
internal Task> CreateOrOpenModalAsync(ModalRef modalRef)
{
OnModalOpenEvent?.Invoke(modalRef);
ReusedModals.Add(modalRef);
return Task.FromResult(modalRef);
}
///
/// close modal dialog
///
///
///
internal Task CloseModalAsync(ModalRef modalRef)
{
if (OnModalCloseEvent != null)
{
return OnModalCloseEvent.Invoke(modalRef);
}
return Task.CompletedTask;
}
///
/// Implement the interface IDisposable
///
public void Dispose()
{
_navigationManager.LocationChanged -= NavigationManager_LocationChanged;
GC.SuppressFinalize(this);
}
public async Task UpdateModalAsync(ModalRef modalRef)
{
await(OnModalUpdateEvent?.Invoke(modalRef) ?? Task.CompletedTask);
}
}
}