WIP
This commit is contained in:
@@ -4,8 +4,9 @@
|
|||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:windows="using:Hyperbar.UI.Windows">
|
xmlns:windows="using:Hyperbar.UI.Windows">
|
||||||
<FlipView
|
<Button>sfsdf</Button>
|
||||||
|
<!--<FlipView
|
||||||
Width="360"
|
Width="360"
|
||||||
ItemTemplateSelector="{Binding Converter={windows:DataTemplateConverter}}"
|
ItemTemplateSelector="{Binding Converter={windows:DataTemplateConverter}}"
|
||||||
ItemsSource="{Binding}" />
|
ItemsSource="{Binding}" />-->
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ public class PrimaryWidgetConfigurationHandler(IMediator mediator,
|
|||||||
IFactory<PrimaryCommandConfiguration, IWidgetComponentViewModel?> factory,
|
IFactory<PrimaryCommandConfiguration, IWidgetComponentViewModel?> factory,
|
||||||
IProvider<PrimaryCommandConfiguration, IWidgetComponentViewModel?> provider,
|
IProvider<PrimaryCommandConfiguration, IWidgetComponentViewModel?> provider,
|
||||||
ICache<(Guid ParentId, Guid Id), PrimaryCommandConfiguration> cache) :
|
ICache<(Guid ParentId, Guid Id), PrimaryCommandConfiguration> cache) :
|
||||||
INotificationHandler<ConfigurationChanged<PrimaryWidgetConfiguration>>
|
INotificationHandler<Changed<PrimaryWidgetConfiguration>>
|
||||||
{
|
{
|
||||||
public async Task Handle(ConfigurationChanged<PrimaryWidgetConfiguration> notification,
|
public async Task Handle(Changed<PrimaryWidgetConfiguration> notification,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
List<KeyValuePair<(Guid ParentId, Guid Id), PrimaryCommandConfiguration>> items = [];
|
List<KeyValuePair<(Guid ParentId, Guid Id), PrimaryCommandConfiguration>> items = [];
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ public static class IServiceCollectionExtensions
|
|||||||
services.AddHandler<WidgetExtensionEnumerator>();
|
services.AddHandler<WidgetExtensionEnumerator>();
|
||||||
services.AddHandler<WidgetExtensionHandler>();
|
services.AddHandler<WidgetExtensionHandler>();
|
||||||
services.AddHandler<WidgetHostHandler>();
|
services.AddHandler<WidgetHostHandler>();
|
||||||
|
services.AddHandler<WidgetStartedHandler>();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
namespace Hyperbar.Widget;
|
||||||
|
|
||||||
|
public class WidgetAvailabilityChangedHandler(IWidgetHost host) :
|
||||||
|
INotificationHandler<Changed<WidgetAvailability>>
|
||||||
|
{
|
||||||
|
public async Task Handle(Changed<WidgetAvailability> args,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (args.Value is WidgetAvailability widgetAvailability)
|
||||||
|
{
|
||||||
|
if (widgetAvailability.Value)
|
||||||
|
{
|
||||||
|
await host.StartAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await host.StopAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,13 +25,18 @@ public class WidgetBuilder :
|
|||||||
})
|
})
|
||||||
.ConfigureServices((context, services) =>
|
.ConfigureServices((context, services) =>
|
||||||
{
|
{
|
||||||
services.AddHostedService<WidgetService>();
|
services.AddSingleton<IWidgetHost, WidgetHost>();
|
||||||
services.AddScoped<IServiceFactory>(provider =>
|
services.AddScoped<IServiceFactory>(provider =>
|
||||||
new ServiceFactory((type, parameters) =>
|
new ServiceFactory((type, parameters) =>
|
||||||
ActivatorUtilities.CreateInstance(provider, type, parameters!)));
|
ActivatorUtilities.CreateInstance(provider, type, parameters!)));
|
||||||
services.AddScoped<IMediator, Mediator>();
|
services.AddScoped<IMediator, Mediator>();
|
||||||
services.AddScoped<IDisposer, Disposer>();
|
services.AddScoped<IDisposer, Disposer>();
|
||||||
services.AddSingleton<IValue<WidgetAvailability>, Value<WidgetAvailability>>();
|
services.AddHandler<WidgetAvailabilityChangedHandler>();
|
||||||
|
services.AddValueChangedNotification<WidgetConfiguration,
|
||||||
|
WidgetAvailability>((config) => (args) =>
|
||||||
|
{
|
||||||
|
args.Value = config.IsEnabled;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,9 +45,7 @@ public class WidgetBuilder :
|
|||||||
public IWidgetHost Build()
|
public IWidgetHost Build()
|
||||||
{
|
{
|
||||||
IHost host = hostBuilder.Build();
|
IHost host = hostBuilder.Build();
|
||||||
|
return host.Services.GetRequiredService<IWidgetHost>();
|
||||||
return (IWidgetHost)ActivatorUtilities.CreateInstance(host.Services,
|
|
||||||
typeof(WidgetHost), host);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IWidgetBuilder UseConfiguration<TConfiguration>(Action<TConfiguration> configurationDelegate)
|
public IWidgetBuilder UseConfiguration<TConfiguration>(Action<TConfiguration> configurationDelegate)
|
||||||
@@ -56,7 +59,6 @@ public class WidgetBuilder :
|
|||||||
}
|
}
|
||||||
|
|
||||||
configurationRegistered = true;
|
configurationRegistered = true;
|
||||||
|
|
||||||
TConfiguration configuration = new();
|
TConfiguration configuration = new();
|
||||||
configurationDelegate(configuration);
|
configurationDelegate(configuration);
|
||||||
|
|
||||||
@@ -88,7 +90,6 @@ public class WidgetBuilder :
|
|||||||
}
|
}
|
||||||
|
|
||||||
viewModelTemplateRegistered = true;
|
viewModelTemplateRegistered = true;
|
||||||
|
|
||||||
hostBuilder.ConfigureServices(services =>
|
hostBuilder.ConfigureServices(services =>
|
||||||
{
|
{
|
||||||
services.AddWidgetTemplate<TViewModel>();
|
services.AddWidgetTemplate<TViewModel>();
|
||||||
@@ -107,7 +108,6 @@ public class WidgetBuilder :
|
|||||||
}
|
}
|
||||||
|
|
||||||
viewModelTemplateRegistered = true;
|
viewModelTemplateRegistered = true;
|
||||||
|
|
||||||
hostBuilder.ConfigureServices(services =>
|
hostBuilder.ConfigureServices(services =>
|
||||||
{
|
{
|
||||||
services.AddWidgetTemplate<TWidgetContent, TWidgetTemplate>();
|
services.AddWidgetTemplate<TWidgetContent, TWidgetTemplate>();
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class WidgetConfiguration
|
|||||||
internal Guid Id { get; set; } = Guid.NewGuid();
|
internal Guid Id { get; set; } = Guid.NewGuid();
|
||||||
|
|
||||||
[JsonInclude]
|
[JsonInclude]
|
||||||
internal bool Enabled { get; set; }
|
internal bool IsEnabled { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class WidgetConfiguration<TConfiguration>;
|
public class WidgetConfiguration<TConfiguration>;
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
|
|
||||||
namespace Hyperbar.Widget;
|
|
||||||
|
|
||||||
public record WidgetConfigurationChanged<TConfiguration> : INotification;
|
|
||||||
@@ -1,14 +1,19 @@
|
|||||||
namespace Hyperbar.Widget;
|
namespace Hyperbar.Widget;
|
||||||
|
|
||||||
public class WidgetConfigurationHandler(IValue<WidgetAvailability> widgetAvailability) :
|
public class WidgetConfigurationHandler(IEnumerable<IConfigurationValueChangedNotification<WidgetConfiguration>>
|
||||||
INotificationHandler<ConfigurationChanged<WidgetConfiguration>>
|
configurationValueChangedNotifications ) :
|
||||||
|
INotificationHandler<Changed<WidgetConfiguration>>
|
||||||
{
|
{
|
||||||
public async Task Handle(ConfigurationChanged<WidgetConfiguration> notification,
|
public async Task Handle(Changed<WidgetConfiguration> args,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (notification.Configuration is WidgetConfiguration configuration)
|
if (args.Value is WidgetConfiguration configuration)
|
||||||
{
|
{
|
||||||
await widgetAvailability.SetAsync(args => args with { Value = configuration.Enabled });
|
foreach (IConfigurationValueChangedNotification<WidgetConfiguration> notification in
|
||||||
|
configurationValueChangedNotifications)
|
||||||
|
{
|
||||||
|
await notification.PublishAsync(configuration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ namespace Hyperbar.Widget;
|
|||||||
public sealed class WidgetHost :
|
public sealed class WidgetHost :
|
||||||
IWidgetHost
|
IWidgetHost
|
||||||
{
|
{
|
||||||
private readonly IHost host;
|
private readonly IServiceProvider services;
|
||||||
private readonly IMediator mediator;
|
private readonly IMediator mediator;
|
||||||
private readonly IProxyService<IMediator> proxyMediator;
|
private readonly IProxyService<IMediator> proxyMediator;
|
||||||
|
|
||||||
public WidgetHost(IHost host,
|
public WidgetHost(IServiceProvider services,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IProxyService<IMediator> proxyMediator)
|
IProxyService<IMediator> proxyMediator)
|
||||||
{
|
{
|
||||||
this.host = host;
|
this.services = services;
|
||||||
this.mediator = mediator;
|
this.mediator = mediator;
|
||||||
this.proxyMediator = proxyMediator;
|
this.proxyMediator = proxyMediator;
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ public sealed class WidgetHost :
|
|||||||
public WidgetConfiguration Configuration =>
|
public WidgetConfiguration Configuration =>
|
||||||
Services.GetRequiredService<WidgetConfiguration>();
|
Services.GetRequiredService<WidgetConfiguration>();
|
||||||
|
|
||||||
public IServiceProvider Services => host.Services;
|
public IServiceProvider Services => services;
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
@@ -33,8 +33,6 @@ public sealed class WidgetHost :
|
|||||||
|
|
||||||
public async Task StartAsync(CancellationToken cancellationToken = default)
|
public async Task StartAsync(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
await host.StartAsync(cancellationToken);
|
|
||||||
|
|
||||||
if (proxyMediator.Proxy is IMediator mediator)
|
if (proxyMediator.Proxy is IMediator mediator)
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(new Started<IWidgetHost>(this),
|
await mediator.PublishAsync(new Started<IWidgetHost>(this),
|
||||||
@@ -45,8 +43,8 @@ public sealed class WidgetHost :
|
|||||||
cancellationToken);
|
cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StopAsync(CancellationToken cancellationToken = default)
|
public Task StopAsync(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
await host.StopAsync(cancellationToken);
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,22 +2,9 @@
|
|||||||
|
|
||||||
namespace Hyperbar.Widget;
|
namespace Hyperbar.Widget;
|
||||||
|
|
||||||
public class WidgetHostHandler(IMediator mediator) :
|
public class WidgetHostHandler :
|
||||||
INotificationHandler<Created<IWidgetHost>>
|
INotificationHandler<Created<IWidgetHost>>
|
||||||
{
|
{
|
||||||
//public async Task Handle(Started<IWidgetHost> notification,
|
|
||||||
// CancellationToken cancellationToken)
|
|
||||||
//{
|
|
||||||
// if (notification.Value is IWidgetHost host)
|
|
||||||
// {
|
|
||||||
// if (host.Services.GetService<IWidgetViewModel>() is IWidgetViewModel viewModel)
|
|
||||||
// {
|
|
||||||
// await mediator.PublishAsync(new Created<IWidgetViewModel>(viewModel),
|
|
||||||
// nameof(WidgetViewModel), cancellationToken);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
public async Task Handle(Created<IWidgetHost> notification,
|
public async Task Handle(Created<IWidgetHost> notification,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Hyperbar.Widget;
|
||||||
|
|
||||||
|
public class WidgetStartedHandler(IMediator mediator) :
|
||||||
|
INotificationHandler<Started<IWidgetHost>>
|
||||||
|
{
|
||||||
|
public async Task Handle(Started<IWidgetHost> notification,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (notification.Value is IWidgetHost host)
|
||||||
|
{
|
||||||
|
if (host.Services.GetService<IWidgetViewModel>() is IWidgetViewModel viewModel)
|
||||||
|
{
|
||||||
|
await mediator.PublishAsync(new Created<IWidgetViewModel>(viewModel),
|
||||||
|
nameof(WidgetViewModel), cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,9 +4,9 @@ namespace Hyperbar.Windows;
|
|||||||
|
|
||||||
public class AppConfigurationChangedHandler(DesktopBar desktopFlyout,
|
public class AppConfigurationChangedHandler(DesktopBar desktopFlyout,
|
||||||
AppConfiguration configuration) :
|
AppConfiguration configuration) :
|
||||||
INotificationHandler<ConfigurationChanged<AppConfiguration>>
|
INotificationHandler<Changed<AppConfiguration>>
|
||||||
{
|
{
|
||||||
public Task Handle(ConfigurationChanged<AppConfiguration> notification, CancellationToken cancellationToken)
|
public Task Handle(Changed<AppConfiguration> notification, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
desktopFlyout.Placement = configuration.Placement;
|
desktopFlyout.Placement = configuration.Placement;
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
namespace Hyperbar;
|
|
||||||
|
|
||||||
public record ConfigurationChanged<TConfiguration>(TConfiguration Configuration) : INotification
|
|
||||||
where TConfiguration :
|
|
||||||
class;
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
namespace Hyperbar;
|
namespace Hyperbar;
|
||||||
|
|
||||||
public class ConfigurationInitializer<TConfiguration>(IConfigurationMonitor<TConfiguration> monitor,
|
public class ConfigurationInitializer<TConfiguration>(IMediator mediator,
|
||||||
|
IConfigurationMonitor<TConfiguration> monitor,
|
||||||
IConfigurationReader<TConfiguration> reader,
|
IConfigurationReader<TConfiguration> reader,
|
||||||
IConfigurationWriter<TConfiguration> writer,
|
IConfigurationWriter<TConfiguration> writer,
|
||||||
IConfigurationFactory<TConfiguration> factory) :
|
IConfigurationFactory<TConfiguration> factory) :
|
||||||
@@ -11,14 +12,16 @@ public class ConfigurationInitializer<TConfiguration>(IConfigurationMonitor<TCon
|
|||||||
{
|
{
|
||||||
public async Task InitializeAsync()
|
public async Task InitializeAsync()
|
||||||
{
|
{
|
||||||
if (!reader.TryRead(out TConfiguration? _))
|
if (!reader.TryRead(out TConfiguration? configuration))
|
||||||
{
|
{
|
||||||
if (factory.Create() is object defaultConfiguration)
|
if (factory.Create() is object defaultConfiguration)
|
||||||
{
|
{
|
||||||
|
configuration = (TConfiguration?)defaultConfiguration;
|
||||||
writer.Write(defaultConfiguration);
|
writer.Write(defaultConfiguration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await mediator.PublishAsync(new Changed<TConfiguration>(configuration));
|
||||||
await monitor.InitializeAsync();
|
await monitor.InitializeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public class ConfigurationMonitor<TConfiguration>(IConfigurationFile<TConfigurat
|
|||||||
{
|
{
|
||||||
if (reader.Read() is { } configuration)
|
if (reader.Read() is { } configuration)
|
||||||
{
|
{
|
||||||
await mediator.PublishAsync(new ConfigurationChanged<TConfiguration>(configuration));
|
await mediator.PublishAsync(new Changed<TConfiguration>(configuration));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public class ConfigurationValueChangedNotification<TConfiguration, TValue>(IMediator mediator,
|
||||||
|
Func<TConfiguration, Action<TValue>> factory) :
|
||||||
|
IConfigurationValueChangedNotification<TConfiguration>
|
||||||
|
where TConfiguration :
|
||||||
|
class
|
||||||
|
where TValue :
|
||||||
|
class, new()
|
||||||
|
{
|
||||||
|
private TValue? value;
|
||||||
|
|
||||||
|
public async Task PublishAsync(TConfiguration configuration)
|
||||||
|
{
|
||||||
|
TValue newValue = new();
|
||||||
|
factory(configuration).Invoke(newValue);
|
||||||
|
|
||||||
|
if (value is null || !value.Equals(newValue))
|
||||||
|
{
|
||||||
|
value = newValue;
|
||||||
|
await mediator.PublishAsync(new Changed<TValue>(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface IConfigurationValueChangedNotification<TConfiguration>
|
||||||
|
{
|
||||||
|
Task PublishAsync(TConfiguration configuration);
|
||||||
|
}
|
||||||
@@ -9,6 +9,20 @@ namespace Hyperbar;
|
|||||||
|
|
||||||
public static class IServiceCollectionExtensions
|
public static class IServiceCollectionExtensions
|
||||||
{
|
{
|
||||||
|
public static IServiceCollection AddValueChangedNotification<TConfiguration, TValue>(this IServiceCollection services,
|
||||||
|
Func<TConfiguration, Action<TValue>> factory)
|
||||||
|
where TConfiguration :
|
||||||
|
class
|
||||||
|
where TValue :
|
||||||
|
class, new()
|
||||||
|
{
|
||||||
|
services.AddSingleton<IConfigurationValueChangedNotification<TConfiguration>>(provider =>
|
||||||
|
new ConfigurationValueChangedNotification<TConfiguration, TValue>(provider.GetRequiredService<IMediator>(),
|
||||||
|
factory));
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
public static IServiceCollection AddCache<TKey, TValue>(this IServiceCollection services)
|
public static IServiceCollection AddCache<TKey, TValue>(this IServiceCollection services)
|
||||||
where TKey :
|
where TKey :
|
||||||
notnull
|
notnull
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
|
|
||||||
namespace Hyperbar;
|
|
||||||
|
|
||||||
public interface IValue<TValue>
|
|
||||||
where TValue :
|
|
||||||
notnull, new()
|
|
||||||
{
|
|
||||||
Task SetAsync(Func<TValue, TValue> updateDelgate);
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
namespace Hyperbar;
|
|
||||||
|
|
||||||
public class Value<TValue>(IMediator mediator) :
|
|
||||||
IValue<TValue>
|
|
||||||
where TValue :
|
|
||||||
notnull, new ()
|
|
||||||
{
|
|
||||||
private TValue? current;
|
|
||||||
|
|
||||||
public async Task SetAsync(Func<TValue, TValue> updateDelgate)
|
|
||||||
{
|
|
||||||
if (updateDelgate.Invoke(current ?? new TValue()) is TValue value)
|
|
||||||
{
|
|
||||||
if (current is null || !value.Equals(current))
|
|
||||||
{
|
|
||||||
current = value;
|
|
||||||
await mediator.PublishAsync(new Changed<TValue>(current));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,6 +5,6 @@ public interface INotificationHandler<in TNotification> :
|
|||||||
where TNotification :
|
where TNotification :
|
||||||
INotification
|
INotification
|
||||||
{
|
{
|
||||||
Task Handle(TNotification notification,
|
Task Handle(TNotification args,
|
||||||
CancellationToken cancellationToken);
|
CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user