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); } } }