Add wallet profile image loading
This commit is contained in:
@@ -86,6 +86,8 @@ public partial class App : Application
|
|||||||
services.AddTransient<ISecurityKeyFactory, SecurityKeyFactory>();
|
services.AddTransient<ISecurityKeyFactory, SecurityKeyFactory>();
|
||||||
services.AddTransient<IWalletStoreFactory, WalletStoreFactory>();
|
services.AddTransient<IWalletStoreFactory, WalletStoreFactory>();
|
||||||
|
|
||||||
|
services.AddTransient<IInitialization, WalletProfileImageInitializer>();
|
||||||
|
|
||||||
services.AddTransient<IItemConfigurationCollection, ItemConfigurationCollection>(provider =>
|
services.AddTransient<IItemConfigurationCollection, ItemConfigurationCollection>(provider =>
|
||||||
{
|
{
|
||||||
IEnumerable<IConfigurationDescriptor<ItemConfiguration>> items =
|
IEnumerable<IConfigurationDescriptor<ItemConfiguration>> items =
|
||||||
@@ -95,6 +97,8 @@ public partial class App : Application
|
|||||||
return new ItemConfigurationCollection(items.ToDictionary(x => x.Name, x => (Func<ItemConfiguration>)(() => x.Value)));
|
return new ItemConfigurationCollection(items.ToDictionary(x => x.Name, x => (Func<ItemConfiguration>)(() => x.Value)));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
services.TryAddSingleton<IDecoratorService<ProfileImage<IImageDescriptor>>, DecoratorService<ProfileImage<IImageDescriptor>>>();
|
||||||
|
|
||||||
services.TryAddSingleton<IDecoratorService<SecurityKey>, DecoratorService<SecurityKey>>();
|
services.TryAddSingleton<IDecoratorService<SecurityKey>, DecoratorService<SecurityKey>>();
|
||||||
services.TryAddSingleton<IDecoratorService<WalletConnection>, DecoratorService<WalletConnection>>();
|
services.TryAddSingleton<IDecoratorService<WalletConnection>, DecoratorService<WalletConnection>>();
|
||||||
|
|
||||||
@@ -107,7 +111,7 @@ public partial class App : Application
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddHandler<ReadProfileImageHandler>();
|
services.AddHandler<CreateProfileImageHandler>();
|
||||||
|
|
||||||
services.AddHandler<QueryWalletHandler>();
|
services.AddHandler<QueryWalletHandler>();
|
||||||
services.AddHandler<ItemHandler>();
|
services.AddHandler<ItemHandler>();
|
||||||
@@ -221,7 +225,7 @@ public partial class App : Application
|
|||||||
services.AddInitializer<WalletCollectionInitializer>();
|
services.AddInitializer<WalletCollectionInitializer>();
|
||||||
|
|
||||||
services.AddHandler<CreateWalletHandler>();
|
services.AddHandler<CreateWalletHandler>();
|
||||||
services.AddHandler<ReadProfileImageHandler>();
|
services.AddHandler<CreateProfileImageHandler>();
|
||||||
|
|
||||||
services.AddTemplate<MainViewModel, MainView>("Main");
|
services.AddTemplate<MainViewModel, MainView>("Main");
|
||||||
services.AddHandler<SynchronizeMainViewModelHandler>();
|
services.AddHandler<SynchronizeMainViewModelHandler>();
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
<PersonPicture
|
<PersonPicture
|
||||||
Width="144"
|
Width="144"
|
||||||
Height="144"
|
Height="144"
|
||||||
DisplayName="{Binding Name}" />
|
DisplayName="{Binding Name}"
|
||||||
|
ProfilePicture="{Binding ImageDescriptor.Image}" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{Binding Name}"
|
Text="{Binding Name}"
|
||||||
TextAlignment="Center"
|
TextAlignment="Center"
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
</ConditionAction.Condition>
|
</ConditionAction.Condition>
|
||||||
<NavigateAction Region="Main" Route="OpenWallet">
|
<NavigateAction Region="Main" Route="OpenWallet">
|
||||||
<Parameter Key="Name" Value="{Binding Name}" />
|
<Parameter Key="Name" Value="{Binding Name}" />
|
||||||
|
<Parameter Key="ImageDescriptor" Value="{Binding ImageDescriptor}" />
|
||||||
</NavigateAction>
|
</NavigateAction>
|
||||||
</ConditionAction>
|
</ConditionAction>
|
||||||
</DataTriggerBehavior>
|
</DataTriggerBehavior>
|
||||||
@@ -29,9 +30,13 @@
|
|||||||
</ConditionAction.Condition>
|
</ConditionAction.Condition>
|
||||||
<NavigateAction Region="Main" Route="OpenWallet">
|
<NavigateAction Region="Main" Route="OpenWallet">
|
||||||
<Parameter Key="Name" Value="{Binding Name}" />
|
<Parameter Key="Name" Value="{Binding Name}" />
|
||||||
|
<Parameter Key="ImageDescriptor" Value="{Binding ImageDescriptor}" />
|
||||||
</NavigateAction>
|
</NavigateAction>
|
||||||
</ConditionAction>
|
</ConditionAction>
|
||||||
</AttachedEventTriggerBehaviour>
|
</AttachedEventTriggerBehaviour>
|
||||||
</Interaction.Behaviors>
|
</Interaction.Behaviors>
|
||||||
<PersonPicture Height="40" DisplayName="{Binding Name}" />
|
<PersonPicture
|
||||||
|
Height="40"
|
||||||
|
DisplayName="{Binding Name}"
|
||||||
|
ProfilePicture="{Binding ImageDescriptor.Image}" />
|
||||||
</ListBoxItem>
|
</ListBoxItem>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using Toolkit.Foundation;
|
||||||
|
|
||||||
|
namespace Wallet;
|
||||||
|
|
||||||
|
public class CreateProfileImageHandler(IFileProvider fileProvider,
|
||||||
|
IImageReader imageReader) :
|
||||||
|
IHandler<CreateEventArgs<ProfileImage>, IImageDescriptor?>
|
||||||
|
{
|
||||||
|
public async Task<IImageDescriptor?> Handle(CreateEventArgs<ProfileImage> args,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (await fileProvider.SelectFiles(new FileFilter("Image files", ["jpg", "jpeg", "png"]))
|
||||||
|
is { Count: 1 } files)
|
||||||
|
{
|
||||||
|
if (files.FirstOrDefault() is string file)
|
||||||
|
{
|
||||||
|
using FileStream stream = File.OpenRead(file);
|
||||||
|
return imageReader.Get(stream, 200, 200, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -62,8 +62,8 @@ public partial class CreateWalletViewModel :
|
|||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public async Task Import() => ImageDescriptor = await Mediator.Handle<ReadEventArgs<ProfileImage>,
|
public async Task Import() => ImageDescriptor = await Mediator.Handle<CreateEventArgs<ProfileImage>,
|
||||||
IImageDescriptor>(Read.As<ProfileImage>());
|
IImageDescriptor>(Create.As<ProfileImage>());
|
||||||
|
|
||||||
protected override void OnPropertyChanged(PropertyChangedEventArgs args)
|
protected override void OnPropertyChanged(PropertyChangedEventArgs args)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ public partial class OpenWalletViewModel : Observable
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? name;
|
private string? name;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private IImageDescriptor imageDescriptor;
|
||||||
|
|
||||||
[MaybeNull]
|
[MaybeNull]
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string password;
|
private string password;
|
||||||
@@ -24,10 +27,13 @@ public partial class OpenWalletViewModel : Observable
|
|||||||
IPublisher publisher,
|
IPublisher publisher,
|
||||||
ISubscriber subscriber,
|
ISubscriber subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
string name) : base(provider, factory, mediator, publisher, subscriber, disposer)
|
string name,
|
||||||
|
IImageDescriptor imageDescriptor) : base(provider, factory, mediator, publisher, subscriber, disposer)
|
||||||
{
|
{
|
||||||
this.validation = validation;
|
this.validation = validation;
|
||||||
|
|
||||||
Name = name;
|
Name = name;
|
||||||
|
ImageDescriptor = imageDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
using Toolkit.Foundation;
|
|
||||||
|
|
||||||
namespace Wallet;
|
|
||||||
|
|
||||||
public class ReadProfileImageHandler(IFileProvider fileProvider,
|
|
||||||
IImageReader imageReader) :
|
|
||||||
IHandler<ReadEventArgs<ProfileImage>, IImageDescriptor?>
|
|
||||||
{
|
|
||||||
public async Task<IImageDescriptor?> Handle(ReadEventArgs<ProfileImage> args,
|
|
||||||
CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
if (await fileProvider.SelectFiles(new FileFilter("Image files", ["jpg", "jpeg", "png"])) is { Count: 1 } files)
|
|
||||||
{
|
|
||||||
if (files.FirstOrDefault() is string file)
|
|
||||||
{
|
|
||||||
await using FileStream stream = File.OpenRead(file);
|
|
||||||
return await imageReader.Get(stream, 200, 200, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -15,11 +15,15 @@ public class SynchronizeMainViewModelHandler(IPublisher publisher,
|
|||||||
is IConfigurationDescriptor<WalletConfiguration> descriptor ? descriptor.Name : null))
|
is IConfigurationDescriptor<WalletConfiguration> descriptor ? descriptor.Name : null))
|
||||||
{
|
{
|
||||||
if (Wallet.Services.GetRequiredService<IConfigurationDescriptor<WalletConfiguration>>()
|
if (Wallet.Services.GetRequiredService<IConfigurationDescriptor<WalletConfiguration>>()
|
||||||
is IConfigurationDescriptor<WalletConfiguration> descriptor)
|
is IConfigurationDescriptor<WalletConfiguration> configuration)
|
||||||
{
|
{
|
||||||
if (Wallet.Services.GetRequiredService<IServiceFactory>() is IServiceFactory factory)
|
if (Wallet.Services.GetRequiredService<IServiceFactory>() is IServiceFactory factory)
|
||||||
{
|
{
|
||||||
if (factory.Create<WalletNavigationViewModel>(args => args.Initialize(), descriptor.Name, selected)
|
IDecoratorService<ProfileImage<IImageDescriptor>> profileImageDecorator =
|
||||||
|
Wallet.Services.GetRequiredService<IDecoratorService<ProfileImage<IImageDescriptor>>>();
|
||||||
|
ProfileImage<IImageDescriptor>? profileImage = profileImageDecorator.Service;
|
||||||
|
|
||||||
|
if (factory.Create<WalletNavigationViewModel>(args => args.Initialize(), configuration.Name, profileImage?.Value, selected)
|
||||||
is WalletNavigationViewModel viewModel)
|
is WalletNavigationViewModel viewModel)
|
||||||
{
|
{
|
||||||
publisher.Publish(Create.As<IMainNavigationViewModel>(viewModel),
|
publisher.Publish(Create.As<IMainNavigationViewModel>(viewModel),
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ public class WalletCollectionInitializer(IHostEnvironment environment,
|
|||||||
IWalletHostCollection Wallets) :
|
IWalletHostCollection Wallets) :
|
||||||
IInitialization
|
IInitialization
|
||||||
{
|
{
|
||||||
public async Task Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
foreach (string wallet in Directory.EnumerateDirectories(Path.Combine(environment.ContentRootPath, "Wallet")))
|
foreach (string wallet in Directory.EnumerateDirectories(Path.Combine(environment.ContentRootPath, "Wallet")))
|
||||||
{
|
{
|
||||||
@@ -16,11 +16,11 @@ public class WalletCollectionInitializer(IHostEnvironment environment,
|
|||||||
string section = $"Wallet:{name}";
|
string section = $"Wallet:{name}";
|
||||||
|
|
||||||
if (componentFactory.Create<WalletComponent,
|
if (componentFactory.Create<WalletComponent,
|
||||||
WalletConfiguration>(section)
|
WalletConfiguration>(section, new WalletConfiguration())
|
||||||
is IComponentHost host)
|
is IComponentHost host)
|
||||||
{
|
{
|
||||||
Wallets.Add(host);
|
Wallets.Add(host);
|
||||||
await host.StartAsync();
|
host.Start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,10 @@ public class WalletComponent(IHostEnvironment environment,
|
|||||||
public override IComponentBuilder Configuring(string key,
|
public override IComponentBuilder Configuring(string key,
|
||||||
IComponentBuilder builder)
|
IComponentBuilder builder)
|
||||||
{
|
{
|
||||||
|
string path = Path.Combine(environment.ContentRootPath, key.Replace(":", "\\"));
|
||||||
builder.SetComponentConfiguration(args =>
|
builder.SetComponentConfiguration(args =>
|
||||||
{
|
{
|
||||||
args.ContentRoot = Path.Combine(environment.ContentRootPath, key.Replace(":", "\\"));
|
args.ContentRoot = Path.Combine(path);
|
||||||
});
|
});
|
||||||
|
|
||||||
return base.Configuring(key, builder);
|
return base.Configuring(key, builder);
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ public partial class WalletNavigationViewModel :
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool isActivated;
|
private bool isActivated;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private IImageDescriptor imageDescriptor;
|
||||||
|
|
||||||
public WalletNavigationViewModel(IServiceProvider provider,
|
public WalletNavigationViewModel(IServiceProvider provider,
|
||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
@@ -35,10 +38,12 @@ public partial class WalletNavigationViewModel :
|
|||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
IContentTemplate template,
|
IContentTemplate template,
|
||||||
string name,
|
string name,
|
||||||
|
IImageDescriptor imageDescriptor,
|
||||||
bool isSelected) : base(provider, factory, mediator, publisher, subscriber, disposer)
|
bool isSelected) : base(provider, factory, mediator, publisher, subscriber, disposer)
|
||||||
{
|
{
|
||||||
Template = template;
|
Template = template;
|
||||||
Name = name;
|
Name = name;
|
||||||
|
ImageDescriptor = imageDescriptor;
|
||||||
IsSelected = isSelected;
|
IsSelected = isSelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Toolkit.Foundation;
|
||||||
|
|
||||||
|
namespace Wallet;
|
||||||
|
|
||||||
|
public class WalletProfileImageInitializer(IHostEnvironment environment,
|
||||||
|
IImageReader reader,
|
||||||
|
IDecoratorService<ProfileImage<IImageDescriptor>> profileImageDecorator) :
|
||||||
|
IInitialization
|
||||||
|
{
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
string file = Path.Combine(environment.ContentRootPath, "Thumbnail.png");
|
||||||
|
if (File.Exists(file))
|
||||||
|
{
|
||||||
|
using FileStream stream = File.OpenRead(file);
|
||||||
|
IImageDescriptor imageDescriptor = reader.Get(stream, 200, 200);
|
||||||
|
|
||||||
|
profileImageDecorator.Set(new ProfileImage<IImageDescriptor>(imageDescriptor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user