Get favourites working
This commit is contained in:
@@ -2,8 +2,7 @@
|
|||||||
x:Class="Bitvault.Avalonia.App"
|
x:Class="Bitvault.Avalonia.App"
|
||||||
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:ui="using:FluentAvalonia.UI.Controls"
|
xmlns:ui="using:FluentAvalonia.UI.Controls">
|
||||||
RequestedThemeVariant="Default">
|
|
||||||
<Application.Styles>
|
<Application.Styles>
|
||||||
<ThemeResources PreferSystemTheme="True" PreferUserAccentColor="True" />
|
<ThemeResources PreferSystemTheme="True" PreferUserAccentColor="True" />
|
||||||
<Style Selector="ui|SettingsExpanderItem">
|
<Style Selector="ui|SettingsExpanderItem">
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ public partial class App : Application
|
|||||||
|
|
||||||
services.AddTemplate<ItemCommandHeaderViewModel, ItemCommandHeaderView>("ItemCommandHeader");
|
services.AddTemplate<ItemCommandHeaderViewModel, ItemCommandHeaderView>("ItemCommandHeader");
|
||||||
|
|
||||||
|
services.AddTemplate<FavouriteItemActionViewModel, FavouriteItemActionView>();
|
||||||
services.AddTemplate<ConfirmItemActionViewModel, ConfirmItemActionView>();
|
services.AddTemplate<ConfirmItemActionViewModel, ConfirmItemActionView>();
|
||||||
services.AddTemplate<DismissItemActionViewModel, DismissItemActionView>();
|
services.AddTemplate<DismissItemActionViewModel, DismissItemActionView>();
|
||||||
services.AddTemplate<ArchiveItemActionViewModel, ArchiveItemActionView>();
|
services.AddTemplate<ArchiveItemActionViewModel, ArchiveItemActionView>();
|
||||||
@@ -108,7 +109,8 @@ public partial class App : Application
|
|||||||
services.AddHandler<ConfirmItemHandler>(ServiceLifetime.Scoped);
|
services.AddHandler<ConfirmItemHandler>(ServiceLifetime.Scoped);
|
||||||
services.AddHandler<ArchiveItemHandler>(ServiceLifetime.Scoped);
|
services.AddHandler<ArchiveItemHandler>(ServiceLifetime.Scoped);
|
||||||
services.AddHandler<UnarchiveItemHandler>(ServiceLifetime.Scoped);
|
services.AddHandler<UnarchiveItemHandler>(ServiceLifetime.Scoped);
|
||||||
|
services.AddHandler<FavouriteItemHandler>(ServiceLifetime.Scoped);
|
||||||
|
services.AddHandler<UnfavouriteItemHandler>(ServiceLifetime.Scoped);
|
||||||
});
|
});
|
||||||
})!);
|
})!);
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,6 @@
|
|||||||
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
||||||
FontSize="16"
|
FontSize="16"
|
||||||
Foreground="{DynamicResource IconForegroundBrush}"
|
Foreground="{DynamicResource IconForegroundBrush}"
|
||||||
Text="" />
|
Text="" />
|
||||||
</Button>
|
</Button>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
<TextBlock
|
<TextBlock
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
||||||
FontSize="18"
|
FontSize="16"
|
||||||
Foreground="{DynamicResource IconForegroundBrush}"
|
Foreground="{DynamicResource IconForegroundBrush}"
|
||||||
Text="" />
|
Text="" />
|
||||||
</Button>
|
</Button>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -16,6 +16,6 @@
|
|||||||
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
||||||
FontSize="16"
|
FontSize="16"
|
||||||
Foreground="{DynamicResource IconForegroundBrush}"
|
Foreground="{DynamicResource IconForegroundBrush}"
|
||||||
Text="" />
|
Text="" />
|
||||||
</Button>
|
</Button>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -16,6 +16,6 @@
|
|||||||
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
||||||
FontSize="16"
|
FontSize="16"
|
||||||
Foreground="{DynamicResource IconForegroundBrush}"
|
Foreground="{DynamicResource IconForegroundBrush}"
|
||||||
Text="" />
|
Text="" />
|
||||||
</Button>
|
</Button>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<UserControl
|
||||||
|
x:Class="Bitvault.Avalonia.FavouriteItemActionView"
|
||||||
|
xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:vm="using:Bitvault"
|
||||||
|
x:DataType="vm:FavouriteItemActionViewModel">
|
||||||
|
<Button
|
||||||
|
Width="{StaticResource ButtonWidth}"
|
||||||
|
Height="{StaticResource ButtonHeight}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Command="{Binding InvokeCommand}"
|
||||||
|
ToolTip.Tip="Edit">
|
||||||
|
<Grid>
|
||||||
|
<TextBlock
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
||||||
|
FontSize="16"
|
||||||
|
Foreground="{DynamicResource IconForegroundBrush}"
|
||||||
|
IsVisible="{Binding !Value}"
|
||||||
|
Text="" />
|
||||||
|
<TextBlock
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
||||||
|
FontSize="16"
|
||||||
|
Foreground="{DynamicResource IconForegroundBrush}"
|
||||||
|
IsVisible="{Binding Value}"
|
||||||
|
Text="" />
|
||||||
|
</Grid>
|
||||||
|
</Button>
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using Avalonia.Controls;
|
||||||
|
|
||||||
|
namespace Bitvault.Avalonia;
|
||||||
|
|
||||||
|
public partial class FavouriteItemActionView : UserControl
|
||||||
|
{
|
||||||
|
public FavouriteItemActionView() => InitializeComponent();
|
||||||
|
}
|
||||||
@@ -5,6 +5,9 @@
|
|||||||
xmlns:vm="using:Bitvault"
|
xmlns:vm="using:Bitvault"
|
||||||
x:DataType="vm:ItemNavigationViewModel"
|
x:DataType="vm:ItemNavigationViewModel"
|
||||||
IsSelected="{Binding Selected}">
|
IsSelected="{Binding Selected}">
|
||||||
|
<ListBoxItem.Resources>
|
||||||
|
<SolidColorBrush x:Key="StarredIconForegroundBrush" Color="#FFEDB120" />
|
||||||
|
</ListBoxItem.Resources>
|
||||||
<Interaction.Behaviors>
|
<Interaction.Behaviors>
|
||||||
<DataTriggerBehavior Binding="{Binding Selected}" Value="True">
|
<DataTriggerBehavior Binding="{Binding Selected}" Value="True">
|
||||||
<NavigateAction
|
<NavigateAction
|
||||||
@@ -17,6 +20,7 @@
|
|||||||
Scope="self">
|
Scope="self">
|
||||||
<NavigateAction.ParameterBindings>
|
<NavigateAction.ParameterBindings>
|
||||||
<ParameterBinding Key="Archived" Value="{Binding Archived}" />
|
<ParameterBinding Key="Archived" Value="{Binding Archived}" />
|
||||||
|
<ParameterBinding Key="Favourite" Value="{Binding Favourite}" />
|
||||||
</NavigateAction.ParameterBindings>
|
</NavigateAction.ParameterBindings>
|
||||||
</NavigateAction>
|
</NavigateAction>
|
||||||
</DataTriggerBehavior>
|
</DataTriggerBehavior>
|
||||||
@@ -25,8 +29,17 @@
|
|||||||
<PersonPicture
|
<PersonPicture
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Height="34"
|
Height="34"
|
||||||
Margin="0"
|
|
||||||
DisplayName="{Binding Name}" />
|
DisplayName="{Binding Name}" />
|
||||||
|
<TextBlock
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="0,0,-2,10"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
VerticalAlignment="Bottom"
|
||||||
|
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
||||||
|
FontSize="16"
|
||||||
|
Foreground="{DynamicResource StarredIconForegroundBrush}"
|
||||||
|
IsVisible="{Binding Favourite}"
|
||||||
|
Text="" />
|
||||||
<StackPanel Grid.Column="1" Margin="12,12,6,12">
|
<StackPanel Grid.Column="1" Margin="12,12,6,12">
|
||||||
<TextBlock FontWeight="SemiBold" Text="{Binding Name}" />
|
<TextBlock FontWeight="SemiBold" Text="{Binding Name}" />
|
||||||
<TextBlock Opacity="0.7" Text="{Binding Name}" />
|
<TextBlock Opacity="0.7" Text="{Binding Name}" />
|
||||||
|
|||||||
@@ -18,19 +18,19 @@ public class AggerateContainerViewModelHandler(IMediator mediator,
|
|||||||
bool selected = true;
|
bool selected = true;
|
||||||
|
|
||||||
if (await mediator.Handle<RequestEventArgs<QueryContainerConfiguration>,
|
if (await mediator.Handle<RequestEventArgs<QueryContainerConfiguration>,
|
||||||
IReadOnlyCollection<(int Id, string? Name)>>(Request.As(new QueryContainerConfiguration
|
IReadOnlyCollection<(int Id, string? Name, bool Favourite, bool Archived)>>(Request.As(new QueryContainerConfiguration
|
||||||
{
|
{
|
||||||
Filter = configuration.Filter,
|
Filter = configuration.Filter,
|
||||||
Query = configuration.Query
|
Query = configuration.Query
|
||||||
})) is IReadOnlyCollection<(int Id, string? Name)> results)
|
})) is IReadOnlyCollection<(int Id, string? Name, bool Favourite, bool Archived)> results)
|
||||||
{
|
{
|
||||||
foreach ((int Id, string? Name) in results)
|
foreach ((int Id, string? Name, bool Favourite, bool Archived) in results)
|
||||||
{
|
{
|
||||||
IServiceScope serviceScope = serviceProvider.CreateScope();
|
IServiceScope serviceScope = serviceProvider.CreateScope();
|
||||||
IServiceFactory serviceFactory = serviceScope.ServiceProvider.GetRequiredService<IServiceFactory>();
|
IServiceFactory serviceFactory = serviceScope.ServiceProvider.GetRequiredService<IServiceFactory>();
|
||||||
IValueStore<Item> valueStore = serviceScope.ServiceProvider.GetRequiredService<IValueStore<Item>>();
|
IValueStore<Item> valueStore = serviceScope.ServiceProvider.GetRequiredService<IValueStore<Item>>();
|
||||||
|
|
||||||
if (serviceFactory.Create<ItemNavigationViewModel>(Id, Name, "Description", selected, configuration.Filter == "Archive") is ItemNavigationViewModel viewModel)
|
if (serviceFactory.Create<ItemNavigationViewModel>(Id, Name, "Description", selected, Favourite, Archived) is ItemNavigationViewModel viewModel)
|
||||||
{
|
{
|
||||||
Item item = new() { Id = Id, Name = Name };
|
Item item = new() { Id = Id, Name = Name };
|
||||||
valueStore.Set(item);
|
valueStore.Set(item);
|
||||||
|
|||||||
@@ -13,5 +13,4 @@ public partial class ArchiveItemActionViewModel(IServiceProvider provider,
|
|||||||
{
|
{
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public void Invoke() => Publisher.Publish(Archive.As<Item>());
|
public void Invoke() => Publisher.Publish(Archive.As<Item>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Bitvault;
|
||||||
|
|
||||||
|
public record Favourite
|
||||||
|
{
|
||||||
|
public static FavouriteEventArgs<TValue> As<TValue>(TValue value) =>
|
||||||
|
new(value);
|
||||||
|
|
||||||
|
public static FavouriteEventArgs<TValue> As<TValue>() where TValue : new() =>
|
||||||
|
new(new TValue());
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace Bitvault;
|
||||||
|
|
||||||
|
public record FavouriteEventArgs<TValue>(TValue Value);
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using Toolkit.Foundation;
|
||||||
|
|
||||||
|
namespace Bitvault;
|
||||||
|
|
||||||
|
public partial class FavouriteItemActionViewModel(IServiceProvider provider,
|
||||||
|
IServiceFactory factory,
|
||||||
|
IMediator mediator,
|
||||||
|
IPublisher publisher,
|
||||||
|
ISubscription subscriber,
|
||||||
|
IDisposer disposer,
|
||||||
|
bool value = false) : Observable<bool>(provider, factory, mediator, publisher, subscriber, disposer, value),
|
||||||
|
IRemovable
|
||||||
|
{
|
||||||
|
[RelayCommand]
|
||||||
|
public void Invoke()
|
||||||
|
{
|
||||||
|
if (!Value)
|
||||||
|
{
|
||||||
|
Value = true;
|
||||||
|
Publisher.Publish(Favourite.As<Item>());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Value = false;
|
||||||
|
Publisher.Publish(Unfavourite.As<Item>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
using Bitvault.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Toolkit.Foundation;
|
||||||
|
|
||||||
|
namespace Bitvault;
|
||||||
|
|
||||||
|
public class FavouriteItemHandler(IValueStore<Item> valueStore,
|
||||||
|
IDbContextFactory<ContainerDbContext> dbContextFactory) :
|
||||||
|
INotificationHandler<FavouriteEventArgs<Item>>
|
||||||
|
{
|
||||||
|
public async Task Handle(FavouriteEventArgs<Item> args)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (valueStore.Value is Item item)
|
||||||
|
{
|
||||||
|
await Task.Run(async () =>
|
||||||
|
{
|
||||||
|
using ContainerDbContext context = await dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
|
if (await context.FindAsync<ItemEntry>(item.Id) is ItemEntry result)
|
||||||
|
{
|
||||||
|
result.State = 1;
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,10 +15,13 @@ public partial class ItemNavigationViewModel(IServiceProvider provider,
|
|||||||
string name,
|
string name,
|
||||||
string description,
|
string description,
|
||||||
bool selected,
|
bool selected,
|
||||||
|
bool favourite,
|
||||||
bool archived) :
|
bool archived) :
|
||||||
Observable(provider, factory, mediator, publisher, subscriber, disposer),
|
Observable(provider, factory, mediator, publisher, subscriber, disposer),
|
||||||
INotificationHandler<ArchiveEventArgs<Item>>,
|
INotificationHandler<ArchiveEventArgs<Item>>,
|
||||||
INotificationHandler<UnarchiveEventArgs<Item>>,
|
INotificationHandler<UnarchiveEventArgs<Item>>,
|
||||||
|
INotificationHandler<FavouriteEventArgs<Item>>,
|
||||||
|
INotificationHandler<UnfavouriteEventArgs<Item>>,
|
||||||
ISelectable,
|
ISelectable,
|
||||||
IRemovable
|
IRemovable
|
||||||
{
|
{
|
||||||
@@ -28,6 +31,9 @@ public partial class ItemNavigationViewModel(IServiceProvider provider,
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? description = description;
|
private string? description = description;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool favourite = favourite;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private int id = id;
|
private int id = id;
|
||||||
|
|
||||||
@@ -42,15 +48,15 @@ public partial class ItemNavigationViewModel(IServiceProvider provider,
|
|||||||
|
|
||||||
public IContentTemplate Template { get; set; } = template;
|
public IContentTemplate Template { get; set; } = template;
|
||||||
|
|
||||||
public Task Handle(ArchiveEventArgs<Item> args)
|
public Task Handle(ArchiveEventArgs<Item> args) =>
|
||||||
{
|
Task.Run(Dispose);
|
||||||
Dispose();
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task Handle(UnarchiveEventArgs<Item> args)
|
public Task Handle(UnarchiveEventArgs<Item> args) =>
|
||||||
{
|
Task.Run(Dispose);
|
||||||
Dispose();
|
|
||||||
return Task.CompletedTask;
|
public Task Handle(FavouriteEventArgs<Item> args) =>
|
||||||
}
|
Task.FromResult(Favourite = true);
|
||||||
|
|
||||||
|
public Task Handle(UnfavouriteEventArgs<Item> args) =>
|
||||||
|
Task.FromResult(Favourite = false);
|
||||||
}
|
}
|
||||||
@@ -18,6 +18,7 @@ public partial class ItemViewModel :
|
|||||||
ISubscription subscriber,
|
ISubscription subscriber,
|
||||||
IDisposer disposer,
|
IDisposer disposer,
|
||||||
IContentTemplate template,
|
IContentTemplate template,
|
||||||
|
bool favourite = false,
|
||||||
bool archived = false) : base(provider, factory, mediator, publisher, subscriber, disposer)
|
bool archived = false) : base(provider, factory, mediator, publisher, subscriber, disposer)
|
||||||
{
|
{
|
||||||
Template = template;
|
Template = template;
|
||||||
@@ -27,6 +28,7 @@ public partial class ItemViewModel :
|
|||||||
{
|
{
|
||||||
Publisher.Publish(Notify.As(Factory.Create<CommandCollection>(new List<IDisposable>
|
Publisher.Publish(Notify.As(Factory.Create<CommandCollection>(new List<IDisposable>
|
||||||
{
|
{
|
||||||
|
Factory.Create<FavouriteItemActionViewModel>(favourite),
|
||||||
Factory.Create<EditItemActionViewModel>(),
|
Factory.Create<EditItemActionViewModel>(),
|
||||||
Factory.Create<ArchiveItemActionViewModel>(),
|
Factory.Create<ArchiveItemActionViewModel>(),
|
||||||
})));
|
})));
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ using Toolkit.Foundation;
|
|||||||
namespace Bitvault;
|
namespace Bitvault;
|
||||||
|
|
||||||
public class QueryContainerHandler(IDbContextFactory<ContainerDbContext> dbContextFactory) :
|
public class QueryContainerHandler(IDbContextFactory<ContainerDbContext> dbContextFactory) :
|
||||||
IHandler<RequestEventArgs<QueryContainerConfiguration>, IReadOnlyCollection<(int Id, string? Name)>>
|
IHandler<RequestEventArgs<QueryContainerConfiguration>, IReadOnlyCollection<(int Id, string? Name, bool Favourite, bool Archived)>>
|
||||||
{
|
{
|
||||||
public async Task<IReadOnlyCollection<(int Id, string? Name)>> Handle(RequestEventArgs<QueryContainerConfiguration> args,
|
public async Task<IReadOnlyCollection<(int Id, string? Name, bool Favourite, bool Archived)>> Handle(RequestEventArgs<QueryContainerConfiguration> args,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
List<(int Id, string? Name)> items = [];
|
List<(int Id, string? Name, bool Favourite, bool Archived)> items = [];
|
||||||
|
|
||||||
if (args.Value is QueryContainerConfiguration queryConfiguration)
|
if (args.Value is QueryContainerConfiguration queryConfiguration)
|
||||||
{
|
{
|
||||||
@@ -44,13 +44,15 @@ public class QueryContainerHandler(IDbContextFactory<ContainerDbContext> dbConte
|
|||||||
return await context.Set<ItemEntry>().Where(predicate).Select(x => new
|
return await context.Set<ItemEntry>().Where(predicate).Select(x => new
|
||||||
{
|
{
|
||||||
x.Id,
|
x.Id,
|
||||||
x.Name
|
x.Name,
|
||||||
|
Favourite = x.State == 1,
|
||||||
|
Archived = x.State == 2
|
||||||
}).OrderBy(x => x.Name).ToListAsync();
|
}).OrderBy(x => x.Name).ToListAsync();
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach (var result in results)
|
foreach (var result in results)
|
||||||
{
|
{
|
||||||
items.Add(new(result.Id, result.Name));
|
items.Add(new(result.Id, result.Name, result.Favourite, result.Archived));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Bitvault;
|
||||||
|
|
||||||
|
public record Unfavourite
|
||||||
|
{
|
||||||
|
public static UnfavouriteEventArgs<TValue> As<TValue>(TValue value) =>
|
||||||
|
new(value);
|
||||||
|
|
||||||
|
public static UnfavouriteEventArgs<TValue> As<TValue>() where TValue : new() =>
|
||||||
|
new(new TValue());
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace Bitvault;
|
||||||
|
|
||||||
|
public record UnfavouriteEventArgs<TValue>(TValue Value);
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using Toolkit.Foundation;
|
||||||
|
|
||||||
|
namespace Bitvault;
|
||||||
|
|
||||||
|
public partial class UnfavouriteItemActionViewModel(IServiceProvider provider,
|
||||||
|
IServiceFactory factory,
|
||||||
|
IMediator mediator,
|
||||||
|
IPublisher publisher,
|
||||||
|
ISubscription subscriber,
|
||||||
|
IDisposer disposer) : Observable(provider, factory, mediator, publisher, subscriber, disposer),
|
||||||
|
IRemovable
|
||||||
|
{
|
||||||
|
[RelayCommand]
|
||||||
|
public void Invoke() => Publisher.Publish(Unfavourite.As<Item>());
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
using Bitvault.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Toolkit.Foundation;
|
||||||
|
|
||||||
|
namespace Bitvault;
|
||||||
|
|
||||||
|
public class UnfavouriteItemHandler(IValueStore<Item> valueStore,
|
||||||
|
IDbContextFactory<ContainerDbContext> dbContextFactory) :
|
||||||
|
INotificationHandler<UnfavouriteEventArgs<Item>>
|
||||||
|
{
|
||||||
|
public async Task Handle(UnfavouriteEventArgs<Item> args)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (valueStore.Value is Item item)
|
||||||
|
{
|
||||||
|
await Task.Run(async () =>
|
||||||
|
{
|
||||||
|
using ContainerDbContext context = await dbContextFactory.CreateDbContextAsync();
|
||||||
|
|
||||||
|
if (await context.FindAsync<ItemEntry>(item.Id) is ItemEntry result)
|
||||||
|
{
|
||||||
|
result.State = 0;
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user