Skip to content

Commit

Permalink
More services
Browse files Browse the repository at this point in the history
  • Loading branch information
WilStead committed Nov 25, 2024
1 parent 3da31ee commit ad364a3
Show file tree
Hide file tree
Showing 14 changed files with 600 additions and 229 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: publish
env:
VERSION: '0.10.1-preview'
VERSION: '0.11.0-preview'
PRERELEASE: true
on:
push:
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ In order to use Tavenem.Wiki.Blazor, the following steps should be taken:
If both the server and the local data store are unavailable, the wiki will remain operational, but will show no content and will not allow any content to be added.

No automatic synchronization occurs from the local data store to the server (for instance when an offline client reestablishes network connectivity). If your app model requires synchronization of offline content to a server, that logic must be implemented separately.

When providing a configuration function (rather than a preconfigured options instance) the following additional properties are available:
- `ArticleRenderManager`: an instance of `IArticleRenderManager`. The overloads of `ConfigureArticleRenderManager` also allow configuring this from dependency injection. If omitted, an instance of the default `ArticleRenderManager` will be used, which always returns `null` for all members.
- `OfflineManager`: an instance of `IOfflineManager`. The overloads of `ConfigureOfflineManager` also allow configuring this from dependency injection. If omitted, an instance of the default `OfflineManager` will be used, which always returns `false` for all members.
1. Add a page with the following content to your client:
```csharp
@page "/wiki/{*route}"
Expand Down
16 changes: 16 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Changelog

## 0.11.0-preview
### Added
- `IArticleRenderManager` and `ArticleRenderManager` to handle custom layout and rendering of wiki articles
- `IOfflineManager` and `OfflineManager` to control offline editing capabilities
### Removed
- `WikiBlazorOptions.ArticleEndMatter` (replaced by `IArticleRenderManager`)
- `WikiBlazorOptions.ArticleEndMatterRenderMode` (replaced by `IArticleRenderManager`)
- `WikiBlazorOptions.ArticleFrontMatter` (replaced by `IArticleRenderManager`)
- `WikiBlazorOptions.ArticleFrontMatterRenderMode` (replaced by `IArticleRenderManager`)
- `WikiBlazorOptions.CanEditOffline` (replaced by `IOfflineManager`)
- `WikiBlazorOptions.IsOfflineDomain` (replaced by `IOfflineManager`)

## 0.10.2-preview
### Updated
- Update dependencies

## 0.10.1-preview
### Fixed
- Preview popups
Expand Down
23 changes: 18 additions & 5 deletions src/Client/Configuration/ServiceExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Tavenem.Wiki.Blazor.Client;
using Tavenem.Wiki.Blazor.Client.Configuration;

namespace Microsoft.Extensions.DependencyInjection;

Expand All @@ -16,7 +17,13 @@ public static class ServiceExtensions
/// <returns>The <see cref="IServiceCollection"/> instance.</returns>
public static IServiceCollection AddWikiClient(
this IServiceCollection services,
WikiBlazorOptions? options = null) => (options ?? new()).Add(services);
WikiBlazorOptions? options = null)
{
var configuredOptions = options is null
? new()
: new WikiBlazorClientOptions(options);
return configuredOptions.Add(services);
}

/// <summary>
/// Add the required services for <c>Tavenem.Wiki.Blazor</c>.
Expand All @@ -28,10 +35,11 @@ public static IServiceCollection AddWikiClient(
public static IServiceCollection AddWikiClient(
this IServiceCollection services,
WikiBlazorOptions options,
Action<WikiBlazorOptions> config)
Action<WikiBlazorClientOptions> config)
{
config.Invoke(options);
return services.AddWikiClient(options);
var configuredOptions = new WikiBlazorClientOptions(options);
config.Invoke(configuredOptions);
return services.AddWikiClient(configuredOptions);
}

/// <summary>
Expand All @@ -42,5 +50,10 @@ public static IServiceCollection AddWikiClient(
/// <returns>The <see cref="IServiceCollection"/> instance.</returns>
public static IServiceCollection AddWikiClient(
this IServiceCollection services,
Action<WikiBlazorOptions> config) => services.AddWikiClient(new(), config);
Action<WikiBlazorClientOptions> config)
{
var options = new WikiBlazorClientOptions();
config.Invoke(options);
return options.Add(services);
}
}
222 changes: 222 additions & 0 deletions src/Client/Configuration/WikiBlazorClientOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
using Microsoft.Extensions.DependencyInjection;
using System.Diagnostics.CodeAnalysis;
using Tavenem.Wiki.Blazor.Client.Services;

namespace Tavenem.Wiki.Blazor.Client.Configuration;

/// <summary>
/// Options for configuring <c>Tavenem.Wiki.Blazor.Client</c>.
/// </summary>
public class WikiBlazorClientOptions() : WikiBlazorOptions
{
private IArticleRenderManager? _articleRenderManager;
private Func<IServiceProvider, IArticleRenderManager>? _articleRenderManagerConfig;

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]
private Type? _articleRenderManagerType;

private IOfflineManager? _offlineManager;
private Func<IServiceProvider, IOfflineManager>? _offlineManagerConfig;

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]
private Type? _offlineManagerType;

/// <summary>
/// <para>
/// Supply an instance of <see cref="IArticleRenderManager"/>.
/// </para>
/// <para>
/// May be omitted to use the default <see cref="ArticleRenderManager"/>.
/// </para>
/// </summary>
public IArticleRenderManager? ArticleRenderManager
{
get => _articleRenderManager;
set
{
_articleRenderManager = value;
_articleRenderManagerConfig = null;
_articleRenderManagerType = null;
}
}

/// <summary>
/// <para>
/// Supply an instance of <see cref="IOfflineManager"/>.
/// </para>
/// <para>
/// May be omitted to use the default <see cref="OfflineManager"/>.
/// </para>
/// </summary>
public IOfflineManager? OfflineManager
{
get => _offlineManager;
set
{
_offlineManager = value;
_offlineManagerConfig = null;
_offlineManagerType = null;
}
}

/// <summary>
/// Constructs a new instance of <see cref="WikiBlazorClientOptions"/>.
/// </summary>
/// <param name="other">
/// An instance of <see cref="WikiBlazorOptions"/> from which to copy settings.
/// </param>
public WikiBlazorClientOptions(WikiBlazorOptions other) : this()
{
AboutPageTitle = other.AboutPageTitle;
AppBar = other.AppBar;
AppBarRenderMode = other.AppBarRenderMode;
CategoriesTitle = other.CategoriesTitle;
CategoryNamespace = other.CategoryNamespace;
CompactLayout = other.CompactLayout;
CompactRouteHostPart = other.CompactRouteHostPart;
CompactRouteHostPosition = other.CompactRouteHostPosition;
CompactRoutePort = other.CompactRoutePort;
ContactPageTitle = other.ContactPageTitle;
ContentsPageTitle = other.ContentsPageTitle;
CopyrightPageTitle = other.CopyrightPageTitle;
CustomAdminNamespaces = other.CustomAdminNamespaces;
CustomReservedNamespaces = other.CustomReservedNamespaces;
DefaultAnonymousPermission = other.DefaultAnonymousPermission;
DefaultRegisteredPermission = other.DefaultRegisteredPermission;
DefaultTableOfContentsDepth = other.DefaultTableOfContentsDepth;
DefaultTableOfContentsTitle = other.DefaultTableOfContentsTitle;
DomainArchivePermission = other.DomainArchivePermission;
FileNamespace = other.FileNamespace;
GroupNamespace = other.GroupNamespace;
HelpPageTitle = other.HelpPageTitle;
InteractiveRenderMode = other.InteractiveRenderMode;
LinkTemplate = other.LinkTemplate;
LoginPath = other.LoginPath;
MainLayout = other.MainLayout;
MainPageTitle = other.MainPageTitle;
MaxFileSize = other.MaxFileSize;
MinimumTableOfContentsHeadings = other.MinimumTableOfContentsHeadings;
PolicyPageTitle = other.PolicyPageTitle;
Postprocessors = other.Postprocessors;
ScriptNamespace = other.ScriptNamespace;
SiteName = other.SiteName;
SystemNamespace = other.SystemNamespace;
TenorAPIKey = other.TenorAPIKey;
TransclusionNamespace = other.TransclusionNamespace;
UserDomains = other.UserDomains;
UserNamespace = other.UserNamespace;
WikiLinkPrefix = other.WikiLinkPrefix;
WikiServerApiRoute = other.WikiServerApiRoute;
}

/// <inheritdoc />
public override IServiceCollection Add(IServiceCollection services)
{
AddArticleRenderManager(services);
AddOfflineManager(services);

return base.Add(services);
}

/// <summary>
/// <para>
/// Supply a type of <see cref="IArticleRenderManager"/>.
/// </para>
/// <para>
/// May be omitted to use the default <see cref="ArticleRenderManager"/>.
/// </para>
/// </summary>
public void ConfigureArticleRenderManager(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type? type)
{
_articleRenderManagerConfig = null;
_articleRenderManager = null;
_articleRenderManagerType = type;
}

/// <summary>
/// <para>
/// Supply a function which returns an instance of <see cref="IArticleRenderManager"/>.
/// </para>
/// <para>
/// May be omitted to use the default <see cref="ArticleRenderManager"/>.
/// </para>
/// </summary>
public void ConfigureArticleRenderManager(Func<IServiceProvider, IArticleRenderManager> config)
{
_articleRenderManagerConfig = config;
_articleRenderManager = null;
_articleRenderManagerType = null;
}

/// <summary>
/// <para>
/// Supply a type of <see cref="IOfflineManager"/>.
/// </para>
/// <para>
/// May be omitted to use the default <see cref="OfflineManager"/>.
/// </para>
/// </summary>
public void ConfigureOfflineManager(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type? type)
{
_offlineManagerConfig = null;
_offlineManager = null;
_offlineManagerType = type;
}

/// <summary>
/// <para>
/// Supply a function which returns an instance of <see cref="IOfflineManager"/>.
/// </para>
/// <para>
/// May be omitted to use the default <see cref="OfflineManager"/>.
/// </para>
/// </summary>
public void ConfigureOfflineManager(Func<IServiceProvider, IOfflineManager> config)
{
_offlineManagerConfig = config;
_offlineManager = null;
_offlineManagerType = null;
}

private void AddArticleRenderManager(IServiceCollection services)
{
if (ArticleRenderManager is not null)
{
services.AddScoped(_ => ArticleRenderManager);
}
else if (_articleRenderManagerConfig is not null)
{
services.AddScoped(_articleRenderManagerConfig);
}
else if (_articleRenderManagerType is not null)
{
services.AddScoped(typeof(IArticleRenderManager), _articleRenderManagerType);
}
else
{
services.AddScoped<IArticleRenderManager, ArticleRenderManager>();
}
}

private void AddOfflineManager(IServiceCollection services)
{
if (OfflineManager is not null)
{
services.AddScoped(_ => OfflineManager);
}
else if (_offlineManagerConfig is not null)
{
services.AddScoped(_offlineManagerConfig);
}
else if (_offlineManagerType is not null)
{
services.AddScoped(typeof(IOfflineManager), _offlineManagerType);
}
else
{
services.AddScoped<IOfflineManager, OfflineManager>();
}
}
}
Loading

0 comments on commit ad364a3

Please sign in to comment.