Start refining the UI

This commit is contained in:
TheXamlGuy
2024-05-30 19:29:56 +01:00
parent a237ab1e66
commit 3a49b731cb
16 changed files with 149 additions and 28 deletions
+3 -2
View File
@@ -93,7 +93,7 @@ public partial class App : Application
services.AddTemplate<CategoriesNavigationViewModel, CategoriesNavigationView>(); services.AddTemplate<CategoriesNavigationViewModel, CategoriesNavigationView>();
services.AddTemplate<ArchiveNavigationViewModel, ArchiveNavigationView>(); services.AddTemplate<ArchiveNavigationViewModel, ArchiveNavigationView>();
services.AddTemplate<OpenLockerViewModel, OpenView>("OpenLocker"); services.AddTemplate<OpenLockerViewModel, OpenLockerView>("OpenLocker");
services.AddScoped<LockerViewModelConfiguration>(); services.AddScoped<LockerViewModelConfiguration>();
@@ -106,7 +106,7 @@ public partial class App : Application
services.AddTemplate<CreateItemActionViewModel, CreateItemActionView>(); services.AddTemplate<CreateItemActionViewModel, CreateItemActionView>();
services.AddTemplate<SearchLockerActionViewModel, SearchLockerActionView>(); services.AddTemplate<SearchLockerActionViewModel, SearchLockerActionView>();
services.AddTemplate<ItemCategoryCollectionViewModel, ItemCategoryCollectionView>("LockerItemCategoryCollection"); services.AddTemplate<ItemCategoryCollectionViewModel, ItemCategoryCollectionView>("ItemCategoryCollection");
services.AddTemplate<ItemCategoryNavigationViewModel, ItemCategoryNavigationView>(); services.AddTemplate<ItemCategoryNavigationViewModel, ItemCategoryNavigationView>();
services.AddHandler<AggerateLockerItemCategoryViewModelHandler>(); services.AddHandler<AggerateLockerItemCategoryViewModelHandler>();
@@ -126,6 +126,7 @@ public partial class App : Application
services.AddTemplate<EditItemActionViewModel, EditItemActionView>(); services.AddTemplate<EditItemActionViewModel, EditItemActionView>();
services.AddTemplate<DeleteItemActionViewModel, DeleteItemActionView>(); services.AddTemplate<DeleteItemActionViewModel, DeleteItemActionView>();
services.AddTemplate<EmptyItemCollectionViewModel, EmptyItemCollectionView>("EmptyItemCollection");
services.AddTemplate<ItemHeaderViewModel, ItemHeaderView>(); services.AddTemplate<ItemHeaderViewModel, ItemHeaderView>();
services.AddTemplate<ItemContentViewModel, ItemContentView>(); services.AddTemplate<ItemContentViewModel, ItemContentView>();
services.AddTemplate<AddItemNavigationViewModel, AddItemNavigationView>(); services.AddTemplate<AddItemNavigationViewModel, AddItemNavigationView>();
+2 -2
View File
@@ -76,8 +76,8 @@
<Compile Update="ItemContentView.axaml.cs"> <Compile Update="ItemContentView.axaml.cs">
<DependentUpon>ItemContentView.axaml</DependentUpon> <DependentUpon>ItemContentView.axaml</DependentUpon>
</Compile> </Compile>
<Compile Update="OpenView.axaml.cs"> <Compile Update="OpenLockerView.axaml.cs">
<DependentUpon>OpenView.axaml</DependentUpon> <DependentUpon>OpenLockerView.axaml</DependentUpon>
</Compile> </Compile>
<Compile Update="ManageNavigationView.axaml.cs"> <Compile Update="ManageNavigationView.axaml.cs">
<DependentUpon>ManageNavigationView.axaml</DependentUpon> <DependentUpon>ManageNavigationView.axaml</DependentUpon>
+1 -1
View File
@@ -28,7 +28,7 @@
</Grid> </Grid>
<Interaction.Behaviors> <Interaction.Behaviors>
<EventTriggerBehavior EventName="Click"> <EventTriggerBehavior EventName="Click">
<NavigateAction Region="Left" Route="LockerItemCategoryCollection"> <NavigateAction Region="Left" Route="ItemCategoryCollection">
<Parameter Key="Transition" Value="FromRight" /> <Parameter Key="Transition" Value="FromRight" />
<Parameter Key="NavigationStackEnabled" Value="{x:True}" /> <Parameter Key="NavigationStackEnabled" Value="{x:True}" />
</NavigateAction> </NavigateAction>
@@ -0,0 +1,30 @@
<UserControl
x:Class="Bitvault.Avalonia.EmptyItemCollectionView"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:Bitvault"
x:DataType="vm:EmptyItemCollectionViewModel">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock
Text="Nothing to see here"
TextAlignment="Center"
Theme="{DynamicResource BodyStrongTextBlockStyle}" />
<HyperlinkButton Content="Let's start securing your items">
<Interaction.Behaviors>
<EventTriggerBehavior EventName="Click">
<NavigateAction Region="Left" Route="ItemCategoryCollection">
<Parameter Key="Transition" Value="FromRight" />
<Parameter Key="NavigationStackEnabled" Value="{x:True}" />
</NavigateAction>
<NavigateAction
Region="{Binding Named, StringFormat='{}{0}:Content'}"
Route="Item"
Scope="self">
<Parameter Key="test" Value="{x:True}" />
<Parameter Key="State" Value="{x:Static vm:ItemState.Write}" />
</NavigateAction>
</EventTriggerBehavior>
</Interaction.Behaviors>
</HyperlinkButton>
</StackPanel>
</UserControl>
@@ -0,0 +1,10 @@
using Avalonia.Controls;
namespace Bitvault.Avalonia;
public partial class EmptyItemCollectionView :
UserControl
{
public EmptyItemCollectionView() =>
InitializeComponent();
}
+22 -1
View File
@@ -4,11 +4,32 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:Bitvault" xmlns:vm="using:Bitvault"
x:DataType="vm:ItemCollectionViewModel"> x:DataType="vm:ItemCollectionViewModel">
<Interaction.Behaviors>
<AttachedBehaviour>
<ConditionAction>
<ConditionAction.Condition>
<ConditionalExpression ForwardChaining="And">
<ComparisonCondition
LeftOperand="{Binding Count}"
Operator="LessThanOrEqual"
RightOperand="0" />
</ConditionalExpression>
</ConditionAction.Condition>
<NavigateAction Region="{Binding Named, StringFormat='{}{0}:Content'}" Route="EmptyItemCollection" />
</ConditionAction>
</AttachedBehaviour>
<DataTriggerBehavior
Binding="{Binding Count}"
ComparisonCondition="LessThanOrEqual"
Value="0">
<NavigateAction Region="{Binding Named, StringFormat='{}{0}:Content'}" Route="EmptyItemCollection" />
</DataTriggerBehavior>
</Interaction.Behaviors>
<ListBox <ListBox
Margin="2,-1,0,0" Margin="2,-1,0,0"
AutoScrollToSelectedItem="True" AutoScrollToSelectedItem="True"
ItemTemplate="{ReflectionBinding Template}" ItemTemplate="{ReflectionBinding Template}"
ItemsSource="{Binding}" ItemsSource="{Binding}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}" SelectedItem="{Binding SelectedItem}"
SelectionMode="Single" /> SelectionMode="Single" />
</UserControl> </UserControl>
+3 -3
View File
@@ -4,10 +4,10 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:Bitvault" xmlns:vm="using:Bitvault"
x:DataType="vm:ItemHeaderViewModel"> x:DataType="vm:ItemHeaderViewModel">
<StackPanel Grid.Column="1" Spacing="18"> <StackPanel Grid.Column="1" Spacing="12">
<PersonPicture <PersonPicture
Width="96" Width="144"
Height="96" Height="144"
DisplayName="{Binding Value}" /> DisplayName="{Binding Value}" />
<TextBox <TextBox
MaxWidth="360" MaxWidth="360"
+12
View File
@@ -24,6 +24,18 @@
<NavigateBackAction Region="Left" /> <NavigateBackAction Region="Left" />
</ConditionAction> </ConditionAction>
</DataTriggerBehavior> </DataTriggerBehavior>
<DataTriggerBehavior
Binding="{Binding SelectedItem}"
ComparisonCondition="Equal"
Value="{x:Null}">
<NavigateAction
Region="{Binding Named, StringFormat='{}{0}:Content'}"
Route="Item"
Scope="self">
<Parameter Key="test" Value="{x:True}" />
<Parameter Key="State" Value="{x:Static vm:ItemState.Write}" />
</NavigateAction>
</DataTriggerBehavior>
</Interaction.Behaviors> </Interaction.Behaviors>
<ScrollViewer Padding="12,12,12,0"> <ScrollViewer Padding="12,12,12,0">
<ItemsControl ItemTemplate="{ReflectionBinding Template}" ItemsSource="{Binding}"> <ItemsControl ItemTemplate="{ReflectionBinding Template}" ItemsSource="{Binding}">
+6 -2
View File
@@ -19,7 +19,9 @@
<ComparisonCondition LeftOperand="{Binding Selected}" RightOperand="True" /> <ComparisonCondition LeftOperand="{Binding Selected}" RightOperand="True" />
</ConditionalExpression> </ConditionalExpression>
</ConditionAction.Condition> </ConditionAction.Condition>
<NavigateAction Region="Main" Route="OpenLocker" /> <NavigateAction Region="Main" Route="OpenLocker">
<Parameter Key="Name" Value="{Binding Name}" />
</NavigateAction>
<ChangePropertyAction <ChangePropertyAction
PropertyName="SelectsOnInvoked" PropertyName="SelectsOnInvoked"
TargetObject="{Binding #NavigationViewItem}" TargetObject="{Binding #NavigationViewItem}"
@@ -47,7 +49,9 @@
<ComparisonCondition LeftOperand="{Binding Opened}" RightOperand="False" /> <ComparisonCondition LeftOperand="{Binding Opened}" RightOperand="False" />
</ConditionalExpression> </ConditionalExpression>
</ConditionAction.Condition> </ConditionAction.Condition>
<NavigateAction Region="Main" Route="OpenLocker" /> <NavigateAction Region="Main" Route="OpenLocker">
<Parameter Key="Name" Value="{Binding Name}" />
</NavigateAction>
</ConditionAction> </ConditionAction>
<ConditionAction> <ConditionAction>
<ConditionAction.Condition> <ConditionAction.Condition>
@@ -1,12 +1,24 @@
<UserControl <UserControl
x:Class="Bitvault.Avalonia.OpenView" x:Class="Bitvault.Avalonia.OpenLockerView"
xmlns="https://github.com/avaloniaui" xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:Bitvault" xmlns:vm="using:Bitvault"
x:DataType="vm:OpenLockerViewModel"> x:DataType="vm:OpenLockerViewModel">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="12">
<PersonPicture
Width="144"
Height="144"
Margin="0,-144,0,0"
DisplayName="{Binding Name}" />
<TextBlock
Text="{Binding Name}"
TextAlignment="Center"
Theme="{DynamicResource SubtitleTextBlockStyle}" />
<TextBox <TextBox
Width="300" Width="360"
Classes="revealPasswordButton" Classes="revealPasswordButton"
PasswordChar="&#x25CF;" PasswordChar="&#x25CF;"
Text="{Binding Password}"> Text="{Binding Password}">
@@ -0,0 +1,9 @@
using Avalonia.Controls;
namespace Bitvault.Avalonia;
public partial class OpenLockerView : UserControl
{
public OpenLockerView() =>
InitializeComponent();
}
-8
View File
@@ -1,8 +0,0 @@
using Avalonia.Controls;
namespace Bitvault.Avalonia;
public partial class OpenView : UserControl
{
public OpenView() => InitializeComponent();
}
+16
View File
@@ -0,0 +1,16 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Toolkit.Foundation;
namespace Bitvault;
public partial class EmptyItemCollectionViewModel(IServiceProvider provider,
IServiceFactory factory,
IMediator mediator,
IPublisher publisher,
ISubscription subscriber,
IDisposer disposer,
NamedComponent named) : Observable(provider, factory, mediator, publisher, subscriber, disposer)
{
[ObservableProperty]
private string named = $"{named}";
}
+10 -5
View File
@@ -10,6 +10,9 @@ public partial class ItemCollectionViewModel :
INotificationHandler<NotifyEventArgs<Search>>, INotificationHandler<NotifyEventArgs<Search>>,
IBackStack IBackStack
{ {
[ObservableProperty]
public string? named;
private LockerViewModelConfiguration configuration; private LockerViewModelConfiguration configuration;
public ItemCollectionViewModel(IServiceProvider provider, public ItemCollectionViewModel(IServiceProvider provider,
@@ -19,20 +22,18 @@ public partial class ItemCollectionViewModel :
ISubscription subscriber, ISubscription subscriber,
IDisposer disposer, IDisposer disposer,
IContentTemplate template, IContentTemplate template,
NamedComponent named,
LockerViewModelConfiguration configuration, LockerViewModelConfiguration configuration,
string? filter = null) : base(provider, factory, mediator, publisher, subscriber, disposer) string? filter = null) : base(provider, factory, mediator, publisher, subscriber, disposer)
{ {
Template = template; Template = template;
Named = $"{named}";
this.configuration = configuration with { Filter = filter }; this.configuration = configuration with { Filter = filter };
} }
public IContentTemplate Template { get; set; } public IContentTemplate Template { get; set; }
public override Task OnDeactivated()
{
return base.OnDeactivated();
}
public Task Handle(NotifyEventArgs<Filter> args) public Task Handle(NotifyEventArgs<Filter> args)
{ {
if (args.Value is Filter filter) if (args.Value is Filter filter)
@@ -66,6 +67,10 @@ public partial class ItemCollectionViewModel :
return base.OnActivated(); return base.OnActivated();
} }
public override Task OnDeactivated()
{
return base.OnDeactivated();
}
protected override IAggerate OnAggerate(object? key) => protected override IAggerate OnAggerate(object? key) =>
Aggerate.With<ItemNavigationViewModel, LockerViewModelConfiguration>(configuration) Aggerate.With<ItemNavigationViewModel, LockerViewModelConfiguration>(configuration)
with { Key = key }; with { Key = key };
+5
View File
@@ -67,6 +67,11 @@ public partial class ItemViewModel :
return Task.CompletedTask; return Task.CompletedTask;
} }
public override void Dispose()
{
Publisher.Publish(Notify.As(Factory.Create<ItemCommandHeaderCollection>(new List<IDisposable>())));
base.Dispose();
}
public Task Handle(CancelEventArgs<Item> args) public Task Handle(CancelEventArgs<Item> args)
{ {
Publisher.Publish(Notify.As(Factory.Create<ItemCommandHeaderCollection>(new List<IDisposable> Publisher.Publish(Notify.As(Factory.Create<ItemCommandHeaderCollection>(new List<IDisposable>
+5 -1
View File
@@ -9,9 +9,13 @@ public partial class OpenLockerViewModel(IServiceProvider provider,
IMediator mediator, IMediator mediator,
IPublisher publisher, IPublisher publisher,
ISubscription subscriber, ISubscription subscriber,
IDisposer disposer) : IDisposer disposer,
string name) :
Observable(provider, factory, mediator, publisher, subscriber, disposer) Observable(provider, factory, mediator, publisher, subscriber, disposer)
{ {
[ObservableProperty]
private string? name = name;
[ObservableProperty] [ObservableProperty]
private string? password; private string? password;