diff --git a/app/Desktop/Dialogs/CheckBox/CheckBoxDialog.axaml b/app/Desktop/Dialogs/CheckBox/CheckBoxDialog.axaml index 41fe853..224714a 100644 --- a/app/Desktop/Dialogs/CheckBox/CheckBoxDialog.axaml +++ b/app/Desktop/Dialogs/CheckBox/CheckBoxDialog.axaml @@ -38,7 +38,7 @@ - + diff --git a/app/Desktop/Dialogs/CheckBox/CheckBoxDialogModel.cs b/app/Desktop/Dialogs/CheckBox/CheckBoxDialogModel.cs index ae84c43..c3346ca 100644 --- a/app/Desktop/Dialogs/CheckBox/CheckBoxDialogModel.cs +++ b/app/Desktop/Dialogs/CheckBox/CheckBoxDialogModel.cs @@ -2,11 +2,11 @@ using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; -using DHT.Utils.Models; +using CommunityToolkit.Mvvm.ComponentModel; namespace DHT.Desktop.Dialogs.CheckBox; -class CheckBoxDialogModel : BaseModel { +class CheckBoxDialogModel : ObservableObject { public string Title { get; init; } = ""; private IReadOnlyList items = Array.Empty(); @@ -29,8 +29,8 @@ class CheckBoxDialogModel : BaseModel { private bool pauseCheckEvents = false; - public bool AreAllSelected => Items.All(static item => item.Checked); - public bool AreNoneSelected => Items.All(static item => !item.Checked); + public bool AreAllSelected => Items.All(static item => item.IsChecked); + public bool AreNoneSelected => Items.All(static item => !item.IsChecked); public void SelectAll() => SetAllChecked(true); public void SelectNone() => SetAllChecked(false); @@ -39,7 +39,7 @@ class CheckBoxDialogModel : BaseModel { pauseCheckEvents = true; foreach (var item in Items) { - item.Checked = isChecked; + item.IsChecked = isChecked; } pauseCheckEvents = false; @@ -52,7 +52,7 @@ class CheckBoxDialogModel : BaseModel { } private void OnItemPropertyChanged(object? sender, PropertyChangedEventArgs e) { - if (!pauseCheckEvents && e.PropertyName == nameof(CheckBoxItem.Checked)) { + if (!pauseCheckEvents && e.PropertyName == nameof(CheckBoxItem.IsChecked)) { UpdateBulkButtons(); } } @@ -61,7 +61,7 @@ class CheckBoxDialogModel : BaseModel { sealed class CheckBoxDialogModel : CheckBoxDialogModel { public new IReadOnlyList> Items { get; } - public IEnumerable> SelectedItems => Items.Where(static item => item.Checked); + public IEnumerable> SelectedItems => Items.Where(static item => item.IsChecked); public CheckBoxDialogModel(IEnumerable> items) { this.Items = new List>(items); diff --git a/app/Desktop/Dialogs/CheckBox/CheckBoxItem.cs b/app/Desktop/Dialogs/CheckBox/CheckBoxItem.cs index 8f197cf..4046a65 100644 --- a/app/Desktop/Dialogs/CheckBox/CheckBoxItem.cs +++ b/app/Desktop/Dialogs/CheckBox/CheckBoxItem.cs @@ -1,17 +1,13 @@ -using DHT.Utils.Models; +using CommunityToolkit.Mvvm.ComponentModel; namespace DHT.Desktop.Dialogs.CheckBox; -class CheckBoxItem : BaseModel { +partial class CheckBoxItem : ObservableObject { public string Title { get; init; } = ""; public object? Item { get; init; } = null; + [ObservableProperty] private bool isChecked = false; - - public bool Checked { - get => isChecked; - set => Change(ref isChecked, value); - } } sealed class CheckBoxItem : CheckBoxItem { diff --git a/app/Desktop/Dialogs/Progress/ProgressDialogModel.cs b/app/Desktop/Dialogs/Progress/ProgressDialogModel.cs index 6176e76..2b5ec92 100644 --- a/app/Desktop/Dialogs/Progress/ProgressDialogModel.cs +++ b/app/Desktop/Dialogs/Progress/ProgressDialogModel.cs @@ -4,11 +4,10 @@ using System.Linq; using System.Threading.Tasks; using Avalonia.Threading; using DHT.Desktop.Common; -using DHT.Utils.Models; namespace DHT.Desktop.Dialogs.Progress; -sealed class ProgressDialogModel : BaseModel { +sealed class ProgressDialogModel { public string Title { get; init; } = ""; public IReadOnlyList Items { get; } = Array.Empty(); diff --git a/app/Desktop/Dialogs/Progress/ProgressItem.cs b/app/Desktop/Dialogs/Progress/ProgressItem.cs index 1f3ec68..5fb7b68 100644 --- a/app/Desktop/Dialogs/Progress/ProgressItem.cs +++ b/app/Desktop/Dialogs/Progress/ProgressItem.cs @@ -1,18 +1,12 @@ -using DHT.Utils.Models; +using CommunityToolkit.Mvvm.ComponentModel; namespace DHT.Desktop.Dialogs.Progress; -sealed class ProgressItem : BaseModel { +sealed partial class ProgressItem : ObservableObject { + [ObservableProperty(Setter = Access.Private)] + [NotifyPropertyChangedFor(nameof(Opacity))] private bool isVisible = false; - public bool IsVisible { - get => isVisible; - private set { - Change(ref isVisible, value); - OnPropertyChanged(nameof(Opacity)); - } - } - public double Opacity => IsVisible ? 1.0 : 0.0; private string message = ""; @@ -20,29 +14,17 @@ sealed class ProgressItem : BaseModel { public string Message { get => message; set { - Change(ref message, value); + SetProperty(ref message, value); IsVisible = !string.IsNullOrEmpty(value); } } + [ObservableProperty] private string items = ""; - public string Items { - get => items; - set => Change(ref items, value); - } - + [ObservableProperty] private int progress = 0; - public int Progress { - get => progress; - set => Change(ref progress, value); - } - + [ObservableProperty] private bool isIndeterminate; - - public bool IsIndeterminate { - get => isIndeterminate; - set => Change(ref isIndeterminate, value); - } } diff --git a/app/Desktop/Dialogs/TextBox/TextBoxDialogModel.cs b/app/Desktop/Dialogs/TextBox/TextBoxDialogModel.cs index cf2f109..3c69a6e 100644 --- a/app/Desktop/Dialogs/TextBox/TextBoxDialogModel.cs +++ b/app/Desktop/Dialogs/TextBox/TextBoxDialogModel.cs @@ -2,11 +2,11 @@ using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; -using DHT.Utils.Models; +using CommunityToolkit.Mvvm.ComponentModel; namespace DHT.Desktop.Dialogs.TextBox; -class TextBoxDialogModel : BaseModel { +class TextBoxDialogModel : ObservableObject { public string Title { get; init; } = ""; public string Description { get; init; } = ""; diff --git a/app/Desktop/Dialogs/TextBox/TextBoxItem.cs b/app/Desktop/Dialogs/TextBox/TextBoxItem.cs index 3c05cb2..2118ec9 100644 --- a/app/Desktop/Dialogs/TextBox/TextBoxItem.cs +++ b/app/Desktop/Dialogs/TextBox/TextBoxItem.cs @@ -1,11 +1,11 @@ using System; using System.Collections; using System.ComponentModel; -using DHT.Utils.Models; +using CommunityToolkit.Mvvm.ComponentModel; namespace DHT.Desktop.Dialogs.TextBox; -class TextBoxItem : BaseModel, INotifyDataErrorInfo { +class TextBoxItem : ObservableObject, INotifyDataErrorInfo { public string Title { get; init; } = ""; public object? Item { get; init; } = null; @@ -17,7 +17,7 @@ class TextBoxItem : BaseModel, INotifyDataErrorInfo { public string Value { get => this.value; set { - Change(ref this.value, value); + SetProperty(ref this.value, value); ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(Value))); } } diff --git a/app/Desktop/Main/Controls/AttachmentFilterPanelModel.cs b/app/Desktop/Main/Controls/AttachmentFilterPanelModel.cs index 7b027dd..251b24d 100644 --- a/app/Desktop/Main/Controls/AttachmentFilterPanelModel.cs +++ b/app/Desktop/Main/Controls/AttachmentFilterPanelModel.cs @@ -2,16 +2,16 @@ using System; using System.Collections.Generic; using System.ComponentModel; using System.Threading.Tasks; +using CommunityToolkit.Mvvm.ComponentModel; using DHT.Desktop.Common; using DHT.Server; using DHT.Server.Data.Filters; using DHT.Server.Database; -using DHT.Utils.Models; using DHT.Utils.Tasks; namespace DHT.Desktop.Main.Controls; -sealed class AttachmentFilterPanelModel : BaseModel, IDisposable { +sealed partial class AttachmentFilterPanelModel : ObservableObject, IDisposable { public sealed record Unit(string Name, uint Scale); private static readonly Unit[] AllUnits = [ @@ -28,25 +28,15 @@ sealed class AttachmentFilterPanelModel : BaseModel, IDisposable { public string FilterStatisticsText { get; private set; } = ""; + [ObservableProperty] private bool limitSize = false; + + [ObservableProperty] private ulong maximumSize = 0L; + + [ObservableProperty] private Unit maximumSizeUnit = AllUnits[0]; - public bool LimitSize { - get => limitSize; - set => Change(ref limitSize, value); - } - - public ulong MaximumSize { - get => maximumSize; - set => Change(ref maximumSize, value); - } - - public Unit MaximumSizeUnit { - get => maximumSizeUnit; - set => Change(ref maximumSizeUnit, value); - } - public IEnumerable Units => AllUnits; private readonly State state; diff --git a/app/Desktop/Main/Controls/MessageFilterPanelModel.cs b/app/Desktop/Main/Controls/MessageFilterPanelModel.cs index f35aeab..0b8b9af 100644 --- a/app/Desktop/Main/Controls/MessageFilterPanelModel.cs +++ b/app/Desktop/Main/Controls/MessageFilterPanelModel.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Avalonia.Controls; +using CommunityToolkit.Mvvm.ComponentModel; using DHT.Desktop.Common; using DHT.Desktop.Dialogs.CheckBox; using DHT.Desktop.Dialogs.Message; @@ -13,12 +14,11 @@ using DHT.Server; using DHT.Server.Data; using DHT.Server.Data.Filters; using DHT.Server.Database; -using DHT.Utils.Models; using DHT.Utils.Tasks; namespace DHT.Desktop.Main.Controls; -sealed class MessageFilterPanelModel : BaseModel, IDisposable { +sealed partial class MessageFilterPanelModel : ObservableObject, IDisposable { private static readonly HashSet FilterProperties = [ nameof(FilterByDate), nameof(StartDate), @@ -35,63 +35,33 @@ sealed class MessageFilterPanelModel : BaseModel, IDisposable { public bool HasAnyFilters => FilterByDate || FilterByChannel || FilterByUser; + [ObservableProperty] private bool filterByDate = false; + + [ObservableProperty] private DateTime? startDate = null; + + [ObservableProperty] private DateTime? endDate = null; + + [ObservableProperty] private bool filterByChannel = false; + + [ObservableProperty] private HashSet? includedChannels = null; + + [ObservableProperty] private bool filterByUser = false; + + [ObservableProperty] private HashSet? includedUsers = null; - public bool FilterByDate { - get => filterByDate; - set => Change(ref filterByDate, value); - } - - public DateTime? StartDate { - get => startDate; - set => Change(ref startDate, value); - } - - public DateTime? EndDate { - get => endDate; - set => Change(ref endDate, value); - } - - public bool FilterByChannel { - get => filterByChannel; - set => Change(ref filterByChannel, value); - } - - public HashSet? IncludedChannels { - get => includedChannels; - set => Change(ref includedChannels, value); - } - - public bool FilterByUser { - get => filterByUser; - set => Change(ref filterByUser, value); - } - - public HashSet? IncludedUsers { - get => includedUsers; - set => Change(ref includedUsers, value); - } - + [ObservableProperty] private string channelFilterLabel = ""; - public string ChannelFilterLabel { - get => channelFilterLabel; - set => Change(ref channelFilterLabel, value); - } - + [ObservableProperty] private string userFilterLabel = ""; - public string UserFilterLabel { - get => userFilterLabel; - set => Change(ref userFilterLabel, value); - } - private readonly Window window; private readonly State state; private readonly string verb; @@ -224,13 +194,13 @@ sealed class MessageFilterPanelModel : BaseModel, IDisposable { items.Add(new CheckBoxItem(channelId) { Title = title, - Checked = IncludedChannels == null || IncludedChannels.Contains(channelId) + IsChecked = IncludedChannels == null || IncludedChannels.Contains(channelId) }); } return items; } - + const string Title = "Included Channels"; List> items; @@ -257,7 +227,7 @@ sealed class MessageFilterPanelModel : BaseModel, IDisposable { checkBoxItems.Add(new CheckBoxItem(user.Id) { Title = discriminator == null ? name : name + " #" + discriminator, - Checked = IncludedUsers == null || IncludedUsers.Contains(user.Id) + IsChecked = IncludedUsers == null || IncludedUsers.Contains(user.Id) }); } @@ -265,7 +235,7 @@ sealed class MessageFilterPanelModel : BaseModel, IDisposable { } const string Title = "Included Users"; - + List> items; try { items = await ProgressDialog.ShowIndeterminate(window, Title, "Loading users...", PrepareUserItems); diff --git a/app/Desktop/Main/Controls/ServerConfigurationPanelModel.cs b/app/Desktop/Main/Controls/ServerConfigurationPanelModel.cs index e094ac0..e48d9bd 100644 --- a/app/Desktop/Main/Controls/ServerConfigurationPanelModel.cs +++ b/app/Desktop/Main/Controls/ServerConfigurationPanelModel.cs @@ -2,47 +2,31 @@ using System; using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using DHT.Desktop.Dialogs.Message; using DHT.Desktop.Server; using DHT.Server; using DHT.Server.Service; using DHT.Utils.Logging; -using DHT.Utils.Models; namespace DHT.Desktop.Main.Controls; -sealed class ServerConfigurationPanelModel : BaseModel, IDisposable { +sealed partial class ServerConfigurationPanelModel : ObservableObject, IDisposable { private static readonly Log Log = Log.ForType(); + [ObservableProperty] + [NotifyPropertyChangedFor(nameof(HasMadeChanges))] private string inputPort; - public string InputPort { - get => inputPort; - set { - Change(ref inputPort, value); - OnPropertyChanged(nameof(HasMadeChanges)); - } - } - + [ObservableProperty] + [NotifyPropertyChangedFor(nameof(HasMadeChanges))] private string inputToken; - public string InputToken { - get => inputToken; - set { - Change(ref inputToken, value); - OnPropertyChanged(nameof(HasMadeChanges)); - } - } - public bool HasMadeChanges => ServerConfiguration.Port.ToString() != InputPort || ServerConfiguration.Token != InputToken; + [ObservableProperty(Setter = Access.Private)] private bool isToggleServerButtonEnabled = true; - public bool IsToggleServerButtonEnabled { - get => isToggleServerButtonEnabled; - set => Change(ref isToggleServerButtonEnabled, value); - } - public string ToggleServerButtonText => server.IsRunning ? "Stop Server" : "Start Server"; private readonly Window window; diff --git a/app/Desktop/Main/Controls/StatusBarModel.cs b/app/Desktop/Main/Controls/StatusBarModel.cs index 400af61..6aad416 100644 --- a/app/Desktop/Main/Controls/StatusBarModel.cs +++ b/app/Desktop/Main/Controls/StatusBarModel.cs @@ -1,15 +1,17 @@ using System; using Avalonia.Threading; +using CommunityToolkit.Mvvm.ComponentModel; using DHT.Server; using DHT.Server.Database; using DHT.Server.Service; -using DHT.Utils.Models; namespace DHT.Desktop.Main.Controls; -sealed class StatusBarModel : BaseModel, IDisposable { +sealed partial class StatusBarModel : ObservableObject, IDisposable { public DatabaseStatistics DatabaseStatistics { get; } + [ObservableProperty(Setter = Access.Private)] + [NotifyPropertyChangedFor(nameof(ServerStatusText))] private ServerManager.Status serverStatus; public string ServerStatusText => serverStatus switch { @@ -38,9 +40,6 @@ sealed class StatusBarModel : BaseModel, IDisposable { } private void OnServerStatusChanged(object? sender, ServerManager.Status e) { - Dispatcher.UIThread.InvokeAsync(() => { - serverStatus = e; - OnPropertyChanged(nameof(ServerStatusText)); - }); + Dispatcher.UIThread.InvokeAsync(() => ServerStatus = e); } } diff --git a/app/Desktop/Main/MainWindowModel.cs b/app/Desktop/Main/MainWindowModel.cs index 045d560..1abfaac 100644 --- a/app/Desktop/Main/MainWindowModel.cs +++ b/app/Desktop/Main/MainWindowModel.cs @@ -3,24 +3,26 @@ using System.IO; using System.Runtime.InteropServices; using System.Threading.Tasks; using Avalonia.Controls; +using CommunityToolkit.Mvvm.ComponentModel; using DHT.Desktop.Dialogs.Message; using DHT.Desktop.Main.Screens; using DHT.Desktop.Server; using DHT.Server; using DHT.Server.Database; using DHT.Utils.Logging; -using DHT.Utils.Models; namespace DHT.Desktop.Main; -sealed class MainWindowModel : BaseModel, IAsyncDisposable { +sealed partial class MainWindowModel : ObservableObject, IAsyncDisposable { private const string DefaultTitle = "Discord History Tracker"; private static readonly Log Log = Log.ForType(); - public string Title { get; private set; } = DefaultTitle; + [ObservableProperty(Setter = Access.Private)] + private string title = DefaultTitle; - public UserControl CurrentScreen { get; private set; } + [ObservableProperty(Setter = Access.Private)] + private UserControl currentScreen; private readonly WelcomeScreen welcomeScreen; private readonly WelcomeScreenModel welcomeScreenModel; @@ -41,7 +43,7 @@ sealed class MainWindowModel : BaseModel, IAsyncDisposable { welcomeScreenModel.DatabaseSelected += OnDatabaseSelected; welcomeScreen = new WelcomeScreen { DataContext = welcomeScreenModel }; - CurrentScreen = welcomeScreen; + currentScreen = welcomeScreen; var dbFile = args.DatabaseFile; if (!string.IsNullOrWhiteSpace(dbFile)) { @@ -93,9 +95,6 @@ sealed class MainWindowModel : BaseModel, IAsyncDisposable { Title = Path.GetFileName(state.Db.Path) + " - " + DefaultTitle; CurrentScreen = new MainContentScreen { DataContext = mainContentScreenModel }; - OnPropertyChanged(nameof(Title)); - OnPropertyChanged(nameof(CurrentScreen)); - window.Focus(); } @@ -112,9 +111,6 @@ sealed class MainWindowModel : BaseModel, IAsyncDisposable { CurrentScreen = welcomeScreen; welcomeScreenModel.DatabaseSelected += OnDatabaseSelected; - - OnPropertyChanged(nameof(Title)); - OnPropertyChanged(nameof(CurrentScreen)); } private async Task DisposeState() { diff --git a/app/Desktop/Main/Pages/AdvancedPageModel.cs b/app/Desktop/Main/Pages/AdvancedPageModel.cs index 656e051..561d893 100644 --- a/app/Desktop/Main/Pages/AdvancedPageModel.cs +++ b/app/Desktop/Main/Pages/AdvancedPageModel.cs @@ -5,11 +5,10 @@ using DHT.Desktop.Dialogs.Message; using DHT.Desktop.Dialogs.Progress; using DHT.Desktop.Main.Controls; using DHT.Server; -using DHT.Utils.Models; namespace DHT.Desktop.Main.Pages; -sealed class AdvancedPageModel : BaseModel, IDisposable { +sealed class AdvancedPageModel : IDisposable { public ServerConfigurationPanelModel ServerConfigurationModel { get; } private readonly Window window; diff --git a/app/Desktop/Main/Pages/AttachmentsPageModel.cs b/app/Desktop/Main/Pages/AttachmentsPageModel.cs index 159bcc0..086e94e 100644 --- a/app/Desktop/Main/Pages/AttachmentsPageModel.cs +++ b/app/Desktop/Main/Pages/AttachmentsPageModel.cs @@ -4,6 +4,7 @@ using System.ComponentModel; using System.Reactive.Linq; using System.Threading.Tasks; using Avalonia.ReactiveUI; +using CommunityToolkit.Mvvm.ComponentModel; using DHT.Desktop.Common; using DHT.Desktop.Main.Controls; using DHT.Server; @@ -12,12 +13,11 @@ using DHT.Server.Data.Aggregations; using DHT.Server.Data.Filters; using DHT.Server.Database; using DHT.Utils.Logging; -using DHT.Utils.Models; using DHT.Utils.Tasks; namespace DHT.Desktop.Main.Pages; -sealed class AttachmentsPageModel : BaseModel, IDisposable { +sealed partial class AttachmentsPageModel : ObservableObject, IDisposable { private static readonly Log Log = Log.ForType(); private static readonly DownloadItemFilter EnqueuedItemFilter = new () { @@ -27,28 +27,24 @@ sealed class AttachmentsPageModel : BaseModel, IDisposable { } }; + [ObservableProperty(Setter = Access.Private)] private bool isToggleDownloadButtonEnabled = true; - public bool IsToggleDownloadButtonEnabled { - get => isToggleDownloadButtonEnabled; - set => Change(ref isToggleDownloadButtonEnabled, value); - } - public string ToggleDownloadButtonText => IsDownloading ? "Stop Downloading" : "Start Downloading"; + [ObservableProperty(Setter = Access.Private)] + [NotifyPropertyChangedFor(nameof(IsRetryFailedOnDownloadsButtonEnabled))] private bool isRetryingFailedDownloads = false; - public bool IsRetryingFailedDownloads { - get => isRetryingFailedDownloads; - set { - isRetryingFailedDownloads = value; - OnPropertyChanged(nameof(IsRetryFailedOnDownloadsButtonEnabled)); - } - } + [ObservableProperty(Setter = Access.Private)] + [NotifyPropertyChangedFor(nameof(IsRetryFailedOnDownloadsButtonEnabled))] + private bool hasFailedDownloads; + + public bool IsRetryFailedOnDownloadsButtonEnabled => !IsRetryingFailedDownloads && hasFailedDownloads; - public bool IsRetryFailedOnDownloadsButtonEnabled => !IsRetryingFailedDownloads && HasFailedDownloads; - - public string DownloadMessage { get; set; } = ""; + [ObservableProperty(Setter = Access.Private)] + private string downloadMessage = ""; + public double DownloadProgress => totalItemsToDownloadCount is null or 0 ? 0.0 : 100.0 * doneItemsCount / totalItemsToDownloadCount.Value; public AttachmentFilterPanelModel FilterModel { get; } @@ -66,7 +62,6 @@ sealed class AttachmentsPageModel : BaseModel, IDisposable { ]; public bool IsDownloading => state.Downloader.IsDownloading; - public bool HasFailedDownloads => statisticsFailed.Items > 0; private readonly State state; private readonly ThrottledTask enqueueDownloadItemsTask; @@ -206,8 +201,6 @@ sealed class AttachmentsPageModel : BaseModel, IDisposable { } private void UpdateStatistics(DownloadStatusStatistics statusStatistics) { - var hadFailedDownloads = HasFailedDownloads; - statisticsEnqueued.Items = statusStatistics.EnqueuedCount; statisticsEnqueued.Size = statusStatistics.EnqueuedSize; @@ -222,10 +215,7 @@ sealed class AttachmentsPageModel : BaseModel, IDisposable { OnPropertyChanged(nameof(StatisticsRows)); - if (hadFailedDownloads != HasFailedDownloads) { - OnPropertyChanged(nameof(HasFailedDownloads)); - OnPropertyChanged(nameof(IsRetryFailedOnDownloadsButtonEnabled)); - } + hasFailedDownloads = statusStatistics.FailedCount > 0; UpdateDownloadMessage(); } @@ -233,7 +223,6 @@ sealed class AttachmentsPageModel : BaseModel, IDisposable { private void UpdateDownloadMessage() { DownloadMessage = IsDownloading ? doneItemsCount.Format() + " / " + (totalItemsToDownloadCount?.Format() ?? "?") : ""; - OnPropertyChanged(nameof(DownloadMessage)); OnPropertyChanged(nameof(DownloadProgress)); } diff --git a/app/Desktop/Main/Pages/DatabasePageModel.cs b/app/Desktop/Main/Pages/DatabasePageModel.cs index 0d1ee15..2bf5d75 100644 --- a/app/Desktop/Main/Pages/DatabasePageModel.cs +++ b/app/Desktop/Main/Pages/DatabasePageModel.cs @@ -20,11 +20,10 @@ using DHT.Server.Database; using DHT.Server.Database.Import; using DHT.Server.Database.Sqlite.Utils; using DHT.Utils.Logging; -using DHT.Utils.Models; namespace DHT.Desktop.Main.Pages; -sealed class DatabasePageModel : BaseModel { +sealed class DatabasePageModel { private static readonly Log Log = Log.ForType(); public IDatabaseFile Db { get; } diff --git a/app/Desktop/Main/Pages/DebugPageModel.cs b/app/Desktop/Main/Pages/DebugPageModel.cs index 96b13ad..c4a5b3e 100644 --- a/app/Desktop/Main/Pages/DebugPageModel.cs +++ b/app/Desktop/Main/Pages/DebugPageModel.cs @@ -9,10 +9,9 @@ using DHT.Desktop.Dialogs.Progress; using DHT.Server; using DHT.Server.Data; using DHT.Server.Service; -using DHT.Utils.Models; namespace DHT.Desktop.Main.Pages { - sealed class DebugPageModel : BaseModel { + sealed class DebugPageModel { public string GenerateChannels { get; set; } = "0"; public string GenerateUsers { get; set; } = "0"; public string GenerateMessages { get; set; } = "0"; @@ -162,10 +161,8 @@ namespace DHT.Desktop.Main.Pages { } } #else -using DHT.Utils.Models; - namespace DHT.Desktop.Main.Pages { - sealed class DebugPageModel : BaseModel { + sealed class DebugPageModel { public string GenerateChannels { get; set; } = "0"; public string GenerateUsers { get; set; } = "0"; public string GenerateMessages { get; set; } = "0"; diff --git a/app/Desktop/Main/Pages/TrackingPageModel.cs b/app/Desktop/Main/Pages/TrackingPageModel.cs index 4308c9a..75def60 100644 --- a/app/Desktop/Main/Pages/TrackingPageModel.cs +++ b/app/Desktop/Main/Pages/TrackingPageModel.cs @@ -3,33 +3,25 @@ using System.Threading; using System.Threading.Tasks; using System.Web; using Avalonia.Controls; +using CommunityToolkit.Mvvm.ComponentModel; using DHT.Desktop.Dialogs.Message; using DHT.Desktop.Discord; using DHT.Desktop.Server; -using DHT.Utils.Models; using static DHT.Desktop.Program; namespace DHT.Desktop.Main.Pages; -sealed class TrackingPageModel : BaseModel { +sealed partial class TrackingPageModel : ObservableObject { + [ObservableProperty(Setter = Access.Private)] private bool isCopyTrackingScriptButtonEnabled = true; - public bool IsCopyTrackingScriptButtonEnabled { - get => isCopyTrackingScriptButtonEnabled; - set => Change(ref isCopyTrackingScriptButtonEnabled, value); - } + [ObservableProperty(Setter = Access.Private)] + [NotifyPropertyChangedFor(nameof(ToggleAppDevToolsButtonText))] + private bool? areDevToolsEnabled = null; - private bool? areDevToolsEnabled; - - private bool? AreDevToolsEnabled { - get => areDevToolsEnabled; - set { - Change(ref areDevToolsEnabled, value); - OnPropertyChanged(nameof(ToggleAppDevToolsButtonText)); - } - } - - public bool IsToggleAppDevToolsButtonEnabled { get; private set; } = false; + [ObservableProperty(Setter = Access.Private)] + [NotifyPropertyChangedFor(nameof(ToggleAppDevToolsButtonText))] + private bool isToggleAppDevToolsButtonEnabled = false; public string ToggleAppDevToolsButtonText { get { @@ -89,14 +81,12 @@ sealed class TrackingPageModel : BaseModel { bool? devToolsEnabled = await DiscordAppSettings.AreDevToolsEnabled(); if (devToolsEnabled.HasValue) { - IsToggleAppDevToolsButtonEnabled = true; AreDevToolsEnabled = devToolsEnabled.Value; + IsToggleAppDevToolsButtonEnabled = true; } else { IsToggleAppDevToolsButtonEnabled = false; } - - OnPropertyChanged(nameof(IsToggleAppDevToolsButtonEnabled)); } public async Task OnClickToggleAppDevTools() { diff --git a/app/Desktop/Main/Pages/ViewerPageModel.cs b/app/Desktop/Main/Pages/ViewerPageModel.cs index 57b750b..bc576d1 100644 --- a/app/Desktop/Main/Pages/ViewerPageModel.cs +++ b/app/Desktop/Main/Pages/ViewerPageModel.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using System.Web; using Avalonia.Controls; using Avalonia.Platform.Storage; +using CommunityToolkit.Mvvm.ComponentModel; using DHT.Desktop.Common; using DHT.Desktop.Dialogs.File; using DHT.Desktop.Dialogs.Message; @@ -18,12 +19,11 @@ using DHT.Server; using DHT.Server.Data.Filters; using DHT.Server.Database.Export; using DHT.Server.Database.Export.Strategy; -using DHT.Utils.Models; using static DHT.Desktop.Program; namespace DHT.Desktop.Main.Pages; -sealed class ViewerPageModel : BaseModel, IDisposable { +sealed partial class ViewerPageModel : ObservableObject, IDisposable { public static readonly ConcurrentBag TemporaryFiles = []; private static readonly FilePickerFileType[] ViewerFileTypes = [ @@ -33,13 +33,9 @@ sealed class ViewerPageModel : BaseModel, IDisposable { public bool DatabaseToolFilterModeKeep { get; set; } = true; public bool DatabaseToolFilterModeRemove { get; set; } = false; + [ObservableProperty] private bool hasFilters = false; - public bool HasFilters { - get => hasFilters; - set => Change(ref hasFilters, value); - } - public MessageFilterPanelModel FilterModel { get; } private readonly Window window; diff --git a/app/Desktop/Main/Screens/WelcomeScreenModel.cs b/app/Desktop/Main/Screens/WelcomeScreenModel.cs index 3000838..1dbd918 100644 --- a/app/Desktop/Main/Screens/WelcomeScreenModel.cs +++ b/app/Desktop/Main/Screens/WelcomeScreenModel.cs @@ -3,25 +3,21 @@ using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using Avalonia.Controls; +using CommunityToolkit.Mvvm.ComponentModel; using DHT.Desktop.Common; using DHT.Desktop.Dialogs.Message; using DHT.Desktop.Dialogs.Progress; using DHT.Server.Database; using DHT.Server.Database.Sqlite.Utils; -using DHT.Utils.Models; namespace DHT.Desktop.Main.Screens; -sealed class WelcomeScreenModel : BaseModel { +sealed partial class WelcomeScreenModel : ObservableObject { public string Version => Program.Version; + [ObservableProperty(Setter = Access.Private)] private bool isOpenOrCreateDatabaseButtonEnabled = true; - public bool IsOpenOrCreateDatabaseButtonEnabled { - get => isOpenOrCreateDatabaseButtonEnabled; - set => Change(ref isOpenOrCreateDatabaseButtonEnabled, value); - } - public event EventHandler? DatabaseSelected; private readonly Window window; diff --git a/app/NuGet.Config b/app/NuGet.Config new file mode 100644 index 0000000..40f00dc --- /dev/null +++ b/app/NuGet.Config @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/Server/Database/DatabaseStatistics.cs b/app/Server/Database/DatabaseStatistics.cs index 2c0a6b3..31b30a1 100644 --- a/app/Server/Database/DatabaseStatistics.cs +++ b/app/Server/Database/DatabaseStatistics.cs @@ -1,4 +1,4 @@ -using DHT.Utils.Models; +using CommunityToolkit.Mvvm.ComponentModel; namespace DHT.Server.Database; @@ -6,41 +6,22 @@ namespace DHT.Server.Database; /// A live view of database statistics. /// Some of the totals are computed asynchronously and may not reflect the most recent version of the database, or may not be available at all until computed for the first time. /// -public sealed class DatabaseStatistics : BaseModel { +public sealed partial class DatabaseStatistics : ObservableObject { + [ObservableProperty(Setter = Access.Internal)] private long totalServers; + + [ObservableProperty(Setter = Access.Internal)] private long totalChannels; + + [ObservableProperty(Setter = Access.Internal)] private long totalUsers; + + [ObservableProperty(Setter = Access.Internal)] private long? totalMessages; + + [ObservableProperty(Setter = Access.Internal)] private long? totalAttachments; + + [ObservableProperty(Setter = Access.Internal)] private long? totalDownloads; - - public long TotalServers { - get => totalServers; - internal set => Change(ref totalServers, value); - } - - public long TotalChannels { - get => totalChannels; - internal set => Change(ref totalChannels, value); - } - - public long TotalUsers { - get => totalUsers; - internal set => Change(ref totalUsers, value); - } - - public long? TotalMessages { - get => totalMessages; - internal set => Change(ref totalMessages, value); - } - - public long? TotalAttachments { - get => totalAttachments; - internal set => Change(ref totalAttachments, value); - } - - public long? TotalDownloads { - get => totalDownloads; - internal set => Change(ref totalDownloads, value); - } } diff --git a/app/Server/Server.csproj b/app/Server/Server.csproj index 2f85b42..73f8b7e 100644 --- a/app/Server/Server.csproj +++ b/app/Server/Server.csproj @@ -11,6 +11,7 @@ + diff --git a/app/Utils/Models/BaseModel.cs b/app/Utils/Models/BaseModel.cs deleted file mode 100644 index 99b9329..0000000 --- a/app/Utils/Models/BaseModel.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel; -using System.Runtime.CompilerServices; -using JetBrains.Annotations; - -namespace DHT.Utils.Models; - -public abstract class BaseModel : INotifyPropertyChanged { - public event PropertyChangedEventHandler? PropertyChanged; - - [NotifyPropertyChangedInvocator] - protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - protected void Change(ref T field, T newValue, [CallerMemberName] string? propertyName = null) { - if (!EqualityComparer.Default.Equals(field, newValue)) { - field = newValue; - OnPropertyChanged(propertyName); - } - } -}