Ionite
10 months ago
12 changed files with 255 additions and 3 deletions
@ -0,0 +1,31 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using CommunityToolkit.Mvvm.ComponentModel; |
||||
using StabilityMatrix.Core.Attributes; |
||||
using StabilityMatrix.Core.Models.Settings; |
||||
using StabilityMatrix.Core.Services; |
||||
|
||||
namespace StabilityMatrix.Avalonia.ViewModels.Settings; |
||||
|
||||
[Transient] |
||||
[ManagedService] |
||||
public partial class NotificationSettingsItem(ISettingsManager settingsManager) : ObservableObject |
||||
{ |
||||
public NotificationKey? Key { get; set; } |
||||
|
||||
[ObservableProperty] |
||||
private NotificationOption? option; |
||||
|
||||
public static IEnumerable<NotificationOption> AvailableOptions => Enum.GetValues<NotificationOption>(); |
||||
|
||||
partial void OnOptionChanged(NotificationOption? oldValue, NotificationOption? newValue) |
||||
{ |
||||
if (Key is null || oldValue is null || newValue is null) |
||||
return; |
||||
|
||||
settingsManager.Transaction(settings => |
||||
{ |
||||
settings.NotificationOptions[Key] = newValue.Value; |
||||
}); |
||||
} |
||||
} |
@ -0,0 +1,51 @@
|
||||
using System.Collections.Generic; |
||||
using System.Collections.Immutable; |
||||
using System.Linq; |
||||
using CommunityToolkit.Mvvm.ComponentModel; |
||||
using FluentAvalonia.UI.Controls; |
||||
using StabilityMatrix.Avalonia.ViewModels.Base; |
||||
using StabilityMatrix.Avalonia.Views.Settings; |
||||
using StabilityMatrix.Core.Attributes; |
||||
using StabilityMatrix.Core.Models.Settings; |
||||
using StabilityMatrix.Core.Services; |
||||
|
||||
namespace StabilityMatrix.Avalonia.ViewModels.Settings; |
||||
|
||||
[View(typeof(NotificationSettingsPage))] |
||||
[Singleton] |
||||
[ManagedService] |
||||
public partial class NotificationSettingsViewModel(ISettingsManager settingsManager) : PageViewModelBase |
||||
{ |
||||
public override string Title => "Notifications"; |
||||
public override IconSource IconSource => new SymbolIconSource { Symbol = Symbol.Alert }; |
||||
|
||||
[ObservableProperty] |
||||
private IReadOnlyList<NotificationSettingsItem> items = []; |
||||
|
||||
public override void OnLoaded() |
||||
{ |
||||
base.OnLoaded(); |
||||
|
||||
Items = GetItems().OrderBy(item => item.Key).ToImmutableArray(); |
||||
} |
||||
|
||||
private IEnumerable<NotificationSettingsItem> GetItems() |
||||
{ |
||||
var settingsOptions = settingsManager.Settings.NotificationOptions; |
||||
|
||||
foreach (var notificationKey in NotificationKey.All.Values) |
||||
{ |
||||
// If in settings, include settings value, otherwise default |
||||
if (!settingsOptions.TryGetValue(notificationKey, out var option)) |
||||
{ |
||||
option = notificationKey.DefaultOption; |
||||
} |
||||
|
||||
yield return new NotificationSettingsItem(settingsManager) |
||||
{ |
||||
Key = notificationKey, |
||||
Option = option |
||||
}; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,61 @@
|
||||
<controls:UserControlBase |
||||
x:Class="StabilityMatrix.Avalonia.Views.Settings.NotificationSettingsPage" |
||||
xmlns="https://github.com/avaloniaui" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
xmlns:controls="clr-namespace:StabilityMatrix.Avalonia.Controls" |
||||
xmlns:converters="clr-namespace:StabilityMatrix.Avalonia.Converters" |
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
||||
xmlns:fluentIcons="clr-namespace:FluentIcons.Avalonia.Fluent;assembly=FluentIcons.Avalonia.Fluent" |
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
||||
xmlns:mocks="clr-namespace:StabilityMatrix.Avalonia.DesignData" |
||||
xmlns:models="clr-namespace:StabilityMatrix.Core.Models.Settings;assembly=StabilityMatrix.Core" |
||||
xmlns:sg="clr-namespace:SpacedGridControl.Avalonia;assembly=SpacedGridControl.Avalonia" |
||||
xmlns:ui="using:FluentAvalonia.UI.Controls" |
||||
xmlns:vmSettings="clr-namespace:StabilityMatrix.Avalonia.ViewModels.Settings" |
||||
d:DataContext="{x:Static mocks:DesignData.NotificationSettingsViewModel}" |
||||
d:DesignHeight="450" |
||||
d:DesignWidth="800" |
||||
x:DataType="vmSettings:NotificationSettingsViewModel" |
||||
mc:Ignorable="d"> |
||||
|
||||
<controls:UserControlBase.Resources> |
||||
<DataTemplate x:Key="ItemTemplate" DataType="vmSettings:NotificationSettingsItem"> |
||||
<controls:Card Padding="16"> |
||||
<Grid ColumnDefinitions="*,Auto"> |
||||
<StackPanel VerticalAlignment="Center"> |
||||
<TextBlock Text="{Binding Key.DisplayName}" /> |
||||
</StackPanel> |
||||
|
||||
<controls:BetterComboBox |
||||
Grid.Column="1" |
||||
ItemsSource="{x:Static vmSettings:NotificationSettingsItem.AvailableOptions}" |
||||
SelectedItem="{Binding Option}"> |
||||
<controls:BetterComboBox.ItemTemplate> |
||||
<DataTemplate x:DataType="models:NotificationOption"> |
||||
<TextBlock> |
||||
<TextBlock.Text> |
||||
<MultiBinding StringFormat="{}{0} - {1}"> |
||||
<Binding Converter="{x:Static converters:EnumAttributeConverters.DisplayName}" /> |
||||
<Binding Converter="{x:Static converters:EnumAttributeConverters.DisplayDescription}" /> |
||||
</MultiBinding> |
||||
</TextBlock.Text> |
||||
</TextBlock> |
||||
</DataTemplate> |
||||
</controls:BetterComboBox.ItemTemplate> |
||||
<controls:BetterComboBox.SelectionBoxItemTemplate> |
||||
<DataTemplate x:DataType="models:NotificationOption"> |
||||
<TextBlock Text="{Binding Converter={x:Static converters:EnumAttributeConverters.DisplayName}}" /> |
||||
</DataTemplate> |
||||
</controls:BetterComboBox.SelectionBoxItemTemplate> |
||||
</controls:BetterComboBox> |
||||
</Grid> |
||||
|
||||
</controls:Card> |
||||
</DataTemplate> |
||||
</controls:UserControlBase.Resources> |
||||
|
||||
<ScrollViewer Padding="16" VerticalScrollBarVisibility="Auto"> |
||||
<ItemsControl ItemTemplate="{StaticResource ItemTemplate}" ItemsSource="{Binding Items}" /> |
||||
</ScrollViewer> |
||||
|
||||
</controls:UserControlBase> |
@ -0,0 +1,13 @@
|
||||
using StabilityMatrix.Avalonia.Controls; |
||||
using StabilityMatrix.Core.Attributes; |
||||
|
||||
namespace StabilityMatrix.Avalonia.Views.Settings; |
||||
|
||||
[Singleton] |
||||
public partial class NotificationSettingsPage : UserControlBase |
||||
{ |
||||
public NotificationSettingsPage() |
||||
{ |
||||
InitializeComponent(); |
||||
} |
||||
} |
@ -0,0 +1,36 @@
|
||||
using System.Diagnostics.CodeAnalysis; |
||||
using System.Text.Json.Serialization; |
||||
using StabilityMatrix.Core.Converters.Json; |
||||
|
||||
namespace StabilityMatrix.Core.Models.Settings; |
||||
|
||||
/// <summary> |
||||
/// Notification Names |
||||
/// </summary> |
||||
[SuppressMessage("ReSharper", "InconsistentNaming")] |
||||
[JsonConverter(typeof(StringJsonConverter<NotificationKey>))] |
||||
public record NotificationKey(string Value) : StringValue(Value) |
||||
{ |
||||
public NotificationOption DefaultOption { get; init; } |
||||
|
||||
public string? DisplayName { get; init; } |
||||
|
||||
public static NotificationKey Inference_PromptCompleted => |
||||
new("Inference_PromptCompleted") |
||||
{ |
||||
DefaultOption = NotificationOption.NativePush, |
||||
DisplayName = "Inference Prompt Completed" |
||||
}; |
||||
|
||||
public static NotificationKey Download_Completed => |
||||
new("Download_Completed") |
||||
{ |
||||
DefaultOption = NotificationOption.NativePush, |
||||
DisplayName = "Download Completed" |
||||
}; |
||||
|
||||
public static Dictionary<string, NotificationKey> All { get; } = GetValues<NotificationKey>(); |
||||
|
||||
/// <inheritdoc /> |
||||
public override string ToString() => base.ToString(); |
||||
} |
@ -0,0 +1,15 @@
|
||||
using System.ComponentModel.DataAnnotations; |
||||
|
||||
namespace StabilityMatrix.Core.Models.Settings; |
||||
|
||||
public enum NotificationOption |
||||
{ |
||||
[Display(Name = "None", Description = "No notification")] |
||||
None, |
||||
|
||||
[Display(Name = "In-App", Description = "Show a toast in the app")] |
||||
AppToast, |
||||
|
||||
[Display(Name = "Desktop", Description = "Native desktop push notification")] |
||||
NativePush |
||||
} |
Loading…
Reference in new issue