From 88d9b27d2f5c853aaf74b2d9ab16a9ddfe94728b Mon Sep 17 00:00:00 2001 From: Wil Stead Date: Mon, 25 Nov 2024 09:06:52 -0500 Subject: [PATCH] Implement services --- .../ExampleWikiOptions.cs | 9 ------ .../Program.cs | 9 +++++- .../Services/CustomArticleRenderManager.cs | 29 +++++++++++++++++ .../Services/CustomOfflineManager.cs | 14 +++++++++ .../Tavenem.Wiki.Blazor.Example/Program.cs | 8 ++++- sample/WebAssembly Example/Program.cs | 5 +-- .../Services/CustomOfflineManager.cs | 14 +++++++++ src/Client/Pages/ArticleView.cs | 11 ++++--- src/Client/Pages/Upload.razor.cs | 7 +++-- src/Client/Services/ClientWikiDataService.cs | 31 ++++++++----------- 10 files changed, 98 insertions(+), 39 deletions(-) create mode 100644 sample/Web App Example/Tavenem.Wiki.Blazor.Example.Client/Services/CustomArticleRenderManager.cs create mode 100644 sample/Web App Example/Tavenem.Wiki.Blazor.Example.Client/Services/CustomOfflineManager.cs create mode 100644 sample/WebAssembly Example/Services/CustomOfflineManager.cs diff --git a/sample/Web App Example/Tavenem.Wiki.Blazor.Example.Client/ExampleWikiOptions.cs b/sample/Web App Example/Tavenem.Wiki.Blazor.Example.Client/ExampleWikiOptions.cs index 6273460..ba95567 100644 --- a/sample/Web App Example/Tavenem.Wiki.Blazor.Example.Client/ExampleWikiOptions.cs +++ b/sample/Web App Example/Tavenem.Wiki.Blazor.Example.Client/ExampleWikiOptions.cs @@ -10,15 +10,6 @@ public static class ExampleWikiOptions { AppBar = typeof(TopAppBar), AppBarRenderMode = RenderMode.InteractiveWebAssembly, - ArticleFrontMatter = page => string.IsNullOrEmpty(page.Title.Namespace) - && string.IsNullOrEmpty(page.Title.Title) - ? typeof(MainFrontMatter) - : null, - ArticleFrontMatterRenderMode = page => string.IsNullOrEmpty(page.Title.Namespace) - && string.IsNullOrEmpty(page.Title.Title) - ? RenderMode.InteractiveWebAssembly - : null, - CanEditOffline = (_, _, _) => ValueTask.FromResult(true), ContactPageTitle = null, ContentsPageTitle = null, CopyrightPageTitle = null, diff --git a/sample/Web App Example/Tavenem.Wiki.Blazor.Example.Client/Program.cs b/sample/Web App Example/Tavenem.Wiki.Blazor.Example.Client/Program.cs index 8897a43..e8ac836 100644 --- a/sample/Web App Example/Tavenem.Wiki.Blazor.Example.Client/Program.cs +++ b/sample/Web App Example/Tavenem.Wiki.Blazor.Example.Client/Program.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Tavenem.Wiki.Blazor.Example; +using Tavenem.Wiki.Blazor.Example.Client.Services; using Tavenem.Wiki.Blazor.Example.Services; var builder = WebAssemblyHostBuilder.CreateDefault(args); @@ -14,6 +15,12 @@ builder.Services.AddScoped(provider => provider.GetRequiredService()); -builder.Services.AddWikiClient(ExampleWikiOptions.Instance); +builder.Services.AddWikiClient( + ExampleWikiOptions.Instance, + config => + { + config.ConfigureArticleRenderManager(typeof(CustomArticleRenderManager)); + config.ConfigureOfflineManager(typeof(CustomOfflineManager)); + }); await builder.Build().RunAsync(); diff --git a/sample/Web App Example/Tavenem.Wiki.Blazor.Example.Client/Services/CustomArticleRenderManager.cs b/sample/Web App Example/Tavenem.Wiki.Blazor.Example.Client/Services/CustomArticleRenderManager.cs new file mode 100644 index 0000000..716ce05 --- /dev/null +++ b/sample/Web App Example/Tavenem.Wiki.Blazor.Example.Client/Services/CustomArticleRenderManager.cs @@ -0,0 +1,29 @@ +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; +using System.Diagnostics.CodeAnalysis; +using Tavenem.Wiki.Blazor.Client.Services; + +namespace Tavenem.Wiki.Blazor.Example.Client.Services; + +public class CustomArticleRenderManager : IArticleRenderManager +{ + /// + [return: DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)(-1))] + public Type? GetArticleEndMatter(Page page) => null; + + /// + public IComponentRenderMode? GetArticleEndMatterRenderMode(Page page) => null; + + /// + [return: DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)(-1))] + public Type? GetArticleFrontMatter(Page page) => string.IsNullOrEmpty(page.Title.Namespace) + && string.IsNullOrEmpty(page.Title.Title) + ? typeof(MainFrontMatter) + : null; + + /// + public IComponentRenderMode? GetArticleFrontMatterRenderMode(Page page) => string.IsNullOrEmpty(page.Title.Namespace) + && string.IsNullOrEmpty(page.Title.Title) + ? RenderMode.InteractiveWebAssembly + : null; +} diff --git a/sample/Web App Example/Tavenem.Wiki.Blazor.Example.Client/Services/CustomOfflineManager.cs b/sample/Web App Example/Tavenem.Wiki.Blazor.Example.Client/Services/CustomOfflineManager.cs new file mode 100644 index 0000000..b6797b2 --- /dev/null +++ b/sample/Web App Example/Tavenem.Wiki.Blazor.Example.Client/Services/CustomOfflineManager.cs @@ -0,0 +1,14 @@ +using Tavenem.Wiki.Blazor.Client.Services; + +namespace Tavenem.Wiki.Blazor.Example.Client.Services; + +public class CustomOfflineManager : IOfflineManager +{ + /// + public ValueTask CanEditOfflineAsync(string title, string wikiNamespace, string? domain) + => ValueTask.FromResult(true); + + /// + public ValueTask IsOfflineDomainAsync(string domain) + => ValueTask.FromResult(false); +} diff --git a/sample/Web App Example/Tavenem.Wiki.Blazor.Example/Program.cs b/sample/Web App Example/Tavenem.Wiki.Blazor.Example/Program.cs index 3ad9d4d..d7eba78 100644 --- a/sample/Web App Example/Tavenem.Wiki.Blazor.Example/Program.cs +++ b/sample/Web App Example/Tavenem.Wiki.Blazor.Example/Program.cs @@ -3,6 +3,7 @@ using Tavenem.DataStorage; using Tavenem.Wiki; using Tavenem.Wiki.Blazor.Example; +using Tavenem.Wiki.Blazor.Example.Client.Services; using Tavenem.Wiki.Blazor.Example.Components; using Tavenem.Wiki.Blazor.Example.Services; @@ -26,7 +27,12 @@ builder.Services.AddWikiServer( ExampleWikiOptions.Instance, - options => options.ConfigureUserManager(typeof(DefaultUserManager))); + config => + { + config.ConfigureArticleRenderManager(typeof(CustomArticleRenderManager)); + config.ConfigureOfflineManager(typeof(CustomOfflineManager)); + config.ConfigureUserManager(typeof(DefaultUserManager)); + }); var archiveText = File.ReadAllText(Path.Combine(builder.Environment.WebRootPath, "archive.json")); var archive = JsonSerializer.Deserialize(archiveText, WikiArchiveJsonSerializerOptions.Instance); diff --git a/sample/WebAssembly Example/Program.cs b/sample/WebAssembly Example/Program.cs index 9ab757c..0456fef 100644 --- a/sample/WebAssembly Example/Program.cs +++ b/sample/WebAssembly Example/Program.cs @@ -36,7 +36,6 @@ var wikiOptions = new WikiBlazorOptions() { AppBar = typeof(TopAppBar), - CanEditOffline = (_, _, _) => ValueTask.FromResult(true), ContactPageTitle = null, ContentsPageTitle = null, CopyrightPageTitle = null, @@ -61,6 +60,8 @@ } } -builder.Services.AddWikiClient(wikiOptions); +builder.Services.AddWikiClient( + wikiOptions, + config => config.ConfigureOfflineManager(typeof(CustomOfflineManager))); await builder.Build().RunAsync(); diff --git a/sample/WebAssembly Example/Services/CustomOfflineManager.cs b/sample/WebAssembly Example/Services/CustomOfflineManager.cs new file mode 100644 index 0000000..439cf31 --- /dev/null +++ b/sample/WebAssembly Example/Services/CustomOfflineManager.cs @@ -0,0 +1,14 @@ +using Tavenem.Wiki.Blazor.Client.Services; + +namespace Tavenem.Wiki.Blazor.Sample.Services; + +public class CustomOfflineManager : IOfflineManager +{ + /// + public ValueTask CanEditOfflineAsync(string title, string wikiNamespace, string? domain) + => ValueTask.FromResult(true); + + /// + public ValueTask IsOfflineDomainAsync(string domain) + => ValueTask.FromResult(false); +} diff --git a/src/Client/Pages/ArticleView.cs b/src/Client/Pages/ArticleView.cs index cfca3f2..5f893a4 100644 --- a/src/Client/Pages/ArticleView.cs +++ b/src/Client/Pages/ArticleView.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Rendering; using System.Diagnostics.CodeAnalysis; +using Tavenem.Wiki.Blazor.Client.Services; namespace Tavenem.Wiki.Blazor.Client.Pages; @@ -34,7 +35,7 @@ public class ArticleView : ComponentBase /// [Parameter] public IWikiUser? User { get; set; } - [Inject, NotNull] private WikiBlazorOptions? WikiBlazorClientOptions { get; set; } + [Inject, NotNull] private IArticleRenderManager? ArticleRenderManager { get; set; } [Inject, NotNull] private WikiOptions? WikiOptions { get; set; } @@ -53,10 +54,10 @@ protected override void BuildRenderTree(RenderTreeBuilder builder) if (!IsDiff && Page is not null) { - var frontMatterType = WikiBlazorClientOptions.GetArticleFrontMatter(Page); + var frontMatterType = ArticleRenderManager.GetArticleFrontMatter(Page); if (frontMatterType is not null) { - var frontMatterRenderMode = WikiBlazorClientOptions.GetArticleFrontMatterRenderMode(Page); + var frontMatterRenderMode = ArticleRenderManager.GetArticleFrontMatterRenderMode(Page); builder.OpenComponent(4, frontMatterType); builder.AddAttribute(5, nameof(WikiComponent.Page), Page); builder.AddAttribute(6, nameof(WikiComponent.CanEdit), CanEdit); @@ -76,10 +77,10 @@ protected override void BuildRenderTree(RenderTreeBuilder builder) if (!IsDiff && Page is not null) { - var endMatterType = WikiBlazorClientOptions.GetArticleFrontMatter(Page); + var endMatterType = ArticleRenderManager.GetArticleEndMatter(Page); if (endMatterType is not null) { - var endMatterRenderMode = WikiBlazorClientOptions.GetArticleFrontMatterRenderMode(Page); + var endMatterRenderMode = ArticleRenderManager.GetArticleEndMatterRenderMode(Page); builder.OpenComponent(11, endMatterType); builder.AddAttribute(12, nameof(WikiComponent.Page), Page); builder.AddAttribute(13, nameof(WikiComponent.CanEdit), CanEdit); diff --git a/src/Client/Pages/Upload.razor.cs b/src/Client/Pages/Upload.razor.cs index f123aaa..f372f66 100644 --- a/src/Client/Pages/Upload.razor.cs +++ b/src/Client/Pages/Upload.razor.cs @@ -42,6 +42,8 @@ public partial class Upload private bool InsufficientSpace { get; set; } + [Inject, NotNull] private IOfflineManager? OfflineManager { get; set; } + private bool IsInteractive { get; set; } [Inject, NotNull] private NavigationManager? NavigationManager { get; set; } @@ -222,10 +224,9 @@ private async Task UploadAsync(bool confirmOverwrite = false) var isLocal = string.IsNullOrEmpty(WikiBlazorClientOptions.WikiServerApiRoute); if (!isLocal - && !string.IsNullOrEmpty(WikiState.WikiDomain) - && WikiBlazorClientOptions.IsOfflineDomain is not null) + && !string.IsNullOrEmpty(WikiState.WikiDomain)) { - isLocal = await WikiBlazorClientOptions.IsOfflineDomain.Invoke(WikiState.WikiDomain); + isLocal = await OfflineManager.IsOfflineDomainAsync(WikiState.WikiDomain); } if (!isLocal && HttpClient is not null) { diff --git a/src/Client/Services/ClientWikiDataService.cs b/src/Client/Services/ClientWikiDataService.cs index 57c20f3..8ee545c 100644 --- a/src/Client/Services/ClientWikiDataService.cs +++ b/src/Client/Services/ClientWikiDataService.cs @@ -23,6 +23,7 @@ public class ClientWikiDataService( WikiDataService wikiDataService, ILoggerFactory loggerFactory, NavigationManager navigationManager, + IOfflineManager offlineManager, IServiceProvider serviceProvider, SnackbarService snackbarService, WikiBlazorOptions wikiBlazorClientOptions, @@ -539,10 +540,9 @@ public Task RestoreArchiveAsync(Archive archive) => PostAsync( var isLocal = string.IsNullOrEmpty(wikiBlazorClientOptions.WikiServerApiRoute); if (!isLocal - && !string.IsNullOrEmpty(wikiState.WikiDomain) - && wikiBlazorClientOptions.IsOfflineDomain is not null) + && !string.IsNullOrEmpty(wikiState.WikiDomain)) { - isLocal = await wikiBlazorClientOptions.IsOfflineDomain.Invoke(wikiState.WikiDomain); + isLocal = await offlineManager.IsOfflineDomainAsync(wikiState.WikiDomain); } ClaimsPrincipal? user = null; AuthenticationState? state = null; @@ -635,10 +635,9 @@ private async Task FetchIntAsync( { var isLocal = string.IsNullOrEmpty(wikiBlazorClientOptions.WikiServerApiRoute); if (!isLocal - && !string.IsNullOrEmpty(wikiState.WikiDomain) - && wikiBlazorClientOptions.IsOfflineDomain is not null) + && !string.IsNullOrEmpty(wikiState.WikiDomain)) { - isLocal = await wikiBlazorClientOptions.IsOfflineDomain.Invoke(wikiState.WikiDomain); + isLocal = await offlineManager.IsOfflineDomainAsync(wikiState.WikiDomain); } ClaimsPrincipal? user = null; AuthenticationState? state = null; @@ -732,10 +731,9 @@ private async Task FetchIntAsync( { var isLocal = string.IsNullOrEmpty(wikiBlazorClientOptions.WikiServerApiRoute); if (!isLocal - && !string.IsNullOrEmpty(wikiState.WikiDomain) - && wikiBlazorClientOptions.IsOfflineDomain is not null) + && !string.IsNullOrEmpty(wikiState.WikiDomain)) { - isLocal = await wikiBlazorClientOptions.IsOfflineDomain.Invoke(wikiState.WikiDomain); + isLocal = await offlineManager.IsOfflineDomainAsync(wikiState.WikiDomain); } ClaimsPrincipal? user = null; AuthenticationState? state = null; @@ -839,10 +837,9 @@ private async Task FetchIntAsync( var isLocal = string.IsNullOrEmpty(wikiBlazorClientOptions.WikiServerApiRoute); if (!isLocal - && !string.IsNullOrEmpty(wikiState.WikiDomain) - && wikiBlazorClientOptions.IsOfflineDomain is not null) + && !string.IsNullOrEmpty(wikiState.WikiDomain)) { - isLocal = await wikiBlazorClientOptions.IsOfflineDomain.Invoke(wikiState.WikiDomain); + isLocal = await offlineManager.IsOfflineDomainAsync(wikiState.WikiDomain); } ClaimsPrincipal? user = null; AuthenticationState? state = null; @@ -954,10 +951,9 @@ private async Task PostAsync( { var isLocal = string.IsNullOrEmpty(wikiBlazorClientOptions.WikiServerApiRoute); if (!isLocal - && !string.IsNullOrEmpty(wikiState.WikiDomain) - && wikiBlazorClientOptions.IsOfflineDomain is not null) + && !string.IsNullOrEmpty(wikiState.WikiDomain)) { - isLocal = await wikiBlazorClientOptions.IsOfflineDomain.Invoke(wikiState.WikiDomain); + isLocal = await offlineManager.IsOfflineDomainAsync(wikiState.WikiDomain); } ClaimsPrincipal? user = null; AuthenticationState? state = null; @@ -1059,10 +1055,9 @@ private async Task PostAsync( var isLocal = string.IsNullOrEmpty(wikiBlazorClientOptions.WikiServerApiRoute); if (!isLocal - && !string.IsNullOrEmpty(wikiState.WikiDomain) - && wikiBlazorClientOptions.IsOfflineDomain is not null) + && !string.IsNullOrEmpty(wikiState.WikiDomain)) { - isLocal = await wikiBlazorClientOptions.IsOfflineDomain.Invoke(wikiState.WikiDomain); + isLocal = await offlineManager.IsOfflineDomainAsync(wikiState.WikiDomain); } ClaimsPrincipal? user = null; AuthenticationState? state = null;