mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-06-05 01:03:44 -04:00
Use nullable
This commit is contained in:
parent
1bf9d9e2e2
commit
e5a2852165
42 changed files with 195 additions and 196 deletions
|
@ -1,6 +1,16 @@
|
|||
namespace DiscordChatExporter.Gui
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace DiscordChatExporter.Gui
|
||||
{
|
||||
public partial class App
|
||||
{
|
||||
private static readonly Assembly Assembly = typeof(App).Assembly;
|
||||
|
||||
public static string Name => Assembly.GetName().Name!;
|
||||
|
||||
public static Version Version => Assembly.GetName().Version!;
|
||||
|
||||
public static string VersionString => Version.ToString(3);
|
||||
}
|
||||
}
|
|
@ -1,11 +1,14 @@
|
|||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
using DiscordChatExporter.Core.Services;
|
||||
using DiscordChatExporter.Core.Services;
|
||||
using DiscordChatExporter.Gui.ViewModels;
|
||||
using DiscordChatExporter.Gui.ViewModels.Framework;
|
||||
using Stylet;
|
||||
using StyletIoC;
|
||||
|
||||
#if !DEBUG
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
#endif
|
||||
|
||||
namespace DiscordChatExporter.Gui
|
||||
{
|
||||
public class Bootstrapper : Bootstrapper<RootViewModel>
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace DiscordChatExporter.Gui.Converters
|
|||
if (value is DateTimeOffset dateTimeOffsetValue)
|
||||
return dateTimeOffsetValue.DateTime;
|
||||
|
||||
return default;
|
||||
return default(DateTime);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
|
@ -22,7 +22,7 @@ namespace DiscordChatExporter.Gui.Converters
|
|||
if (value is DateTime dateTimeValue)
|
||||
return new DateTimeOffset(dateTimeValue);
|
||||
|
||||
return default;
|
||||
return default(DateTimeOffset);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,12 +10,12 @@ namespace DiscordChatExporter.Gui.Converters
|
|||
{
|
||||
public static ExportFormatToStringConverter Instance { get; } = new ExportFormatToStringConverter();
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
public object? Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is ExportFormat exportFormatValue)
|
||||
return exportFormatValue.GetDisplayName();
|
||||
|
||||
return default;
|
||||
return default(string);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace DiscordChatExporter.Gui.Converters
|
|||
if (value is bool boolValue)
|
||||
return !boolValue;
|
||||
|
||||
return default;
|
||||
return default(bool);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
|
@ -22,7 +22,7 @@ namespace DiscordChatExporter.Gui.Converters
|
|||
if (value is bool boolValue)
|
||||
return !boolValue;
|
||||
|
||||
return default;
|
||||
return default(bool);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
<Version>2.15</Version>
|
||||
<Company>Tyrrrz</Company>
|
||||
<Copyright>Copyright (c) Alexey Golub</Copyright>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWPF>true</UseWPF>
|
||||
<ApplicationIcon>../favicon.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
|
@ -19,11 +20,11 @@
|
|||
<PackageReference Include="Gress" Version="1.1.1" />
|
||||
<PackageReference Include="MaterialDesignColors" Version="1.2.0" />
|
||||
<PackageReference Include="MaterialDesignThemes" Version="2.6.0" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.0.1" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.3" />
|
||||
<PackageReference Include="Ookii.Dialogs.Wpf" Version="1.1.0" />
|
||||
<PackageReference Include="PropertyChanged.Fody" Version="3.1.3" />
|
||||
<PackageReference Include="Stylet" Version="1.3.0" />
|
||||
<PackageReference Include="Tyrrrz.Extensions" Version="1.6.3" />
|
||||
<PackageReference Include="Tyrrrz.Extensions" Version="1.6.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using DiscordChatExporter.Core.Services;
|
||||
using Onova;
|
||||
using Onova.Exceptions;
|
||||
using Onova.Services;
|
||||
|
@ -13,10 +12,10 @@ namespace DiscordChatExporter.Gui.Services
|
|||
new GithubPackageResolver("Tyrrrz", "DiscordChatExporter", "DiscordChatExporter.zip"),
|
||||
new ZipPackageExtractor());
|
||||
|
||||
private Version _updateVersion;
|
||||
private Version? _updateVersion;
|
||||
private bool _updaterLaunched;
|
||||
|
||||
public async Task<Version> CheckForUpdatesAsync()
|
||||
public async Task<Version?> CheckForUpdatesAsync()
|
||||
{
|
||||
var check = await _updateManager.CheckForUpdatesAsync();
|
||||
return check.CanUpdate ? check.LastVersion : null;
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace DiscordChatExporter.Gui.ViewModels.Components
|
|||
{
|
||||
public Channel Model { get; set; }
|
||||
|
||||
public string Category { get; set; }
|
||||
public string? Category { get; set; }
|
||||
}
|
||||
|
||||
public partial class ChannelViewModel
|
||||
|
|
|
@ -6,7 +6,6 @@ using DiscordChatExporter.Core.Services;
|
|||
using DiscordChatExporter.Core.Services.Helpers;
|
||||
using DiscordChatExporter.Gui.ViewModels.Components;
|
||||
using DiscordChatExporter.Gui.ViewModels.Framework;
|
||||
using Tyrrrz.Extensions;
|
||||
|
||||
namespace DiscordChatExporter.Gui.ViewModels.Dialogs
|
||||
{
|
||||
|
@ -21,12 +20,12 @@ namespace DiscordChatExporter.Gui.ViewModels.Dialogs
|
|||
|
||||
public bool IsSingleChannel => Channels.Count == 1;
|
||||
|
||||
public string OutputPath { get; set; }
|
||||
public string? OutputPath { get; set; }
|
||||
|
||||
public IReadOnlyList<ExportFormat> AvailableFormats =>
|
||||
Enum.GetValues(typeof(ExportFormat)).Cast<ExportFormat>().ToArray();
|
||||
|
||||
public ExportFormat SelectedFormat { get; set; } = ExportFormat.HtmlDark;
|
||||
public ExportFormat SelectedFormat { get; set; }
|
||||
|
||||
public DateTimeOffset? After { get; set; }
|
||||
|
||||
|
@ -38,11 +37,6 @@ namespace DiscordChatExporter.Gui.ViewModels.Dialogs
|
|||
{
|
||||
_dialogManager = dialogManager;
|
||||
_settingsService = settingsService;
|
||||
}
|
||||
|
||||
protected override void OnViewLoaded()
|
||||
{
|
||||
base.OnViewLoaded();
|
||||
|
||||
// Persist preferences
|
||||
SelectedFormat = _settingsService.LastExportFormat;
|
||||
|
@ -85,7 +79,7 @@ namespace DiscordChatExporter.Gui.ViewModels.Dialogs
|
|||
}
|
||||
|
||||
// If canceled - return
|
||||
if (OutputPath.IsNullOrWhiteSpace())
|
||||
if (string.IsNullOrWhiteSpace(OutputPath))
|
||||
return;
|
||||
|
||||
// Close dialog
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.IO;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using Microsoft.Win32;
|
||||
|
@ -22,10 +23,10 @@ namespace DiscordChatExporter.Gui.ViewModels.Framework
|
|||
var view = _viewManager.CreateAndBindViewForModelIfNecessary(dialogScreen);
|
||||
|
||||
// Set up event routing that will close the view when called from viewmodel
|
||||
void OnDialogOpened(object sender, DialogOpenedEventArgs openArgs)
|
||||
void OnDialogOpened(object? sender, DialogOpenedEventArgs openArgs)
|
||||
{
|
||||
// Delegate to close the dialog and unregister event handler
|
||||
void OnScreenClosed(object o, CloseEventArgs closeArgs)
|
||||
void OnScreenClosed(object? o, EventArgs closeArgs)
|
||||
{
|
||||
openArgs.Session.Close();
|
||||
dialogScreen.Closed -= OnScreenClosed;
|
||||
|
@ -41,7 +42,7 @@ namespace DiscordChatExporter.Gui.ViewModels.Framework
|
|||
return dialogScreen.DialogResult;
|
||||
}
|
||||
|
||||
public string PromptSaveFilePath(string filter = "All files|*.*", string defaultFilePath = "")
|
||||
public string? PromptSaveFilePath(string filter = "All files|*.*", string defaultFilePath = "")
|
||||
{
|
||||
// Create dialog
|
||||
var dialog = new SaveFileDialog
|
||||
|
@ -56,7 +57,7 @@ namespace DiscordChatExporter.Gui.ViewModels.Framework
|
|||
return dialog.ShowDialog() == true ? dialog.FileName : null;
|
||||
}
|
||||
|
||||
public string PromptDirectoryPath(string defaultDirPath = "")
|
||||
public string? PromptDirectoryPath(string defaultDirPath = "")
|
||||
{
|
||||
// Create dialog
|
||||
var dialog = new VistaFolderBrowserDialog
|
||||
|
|
|
@ -1,22 +1,18 @@
|
|||
using Stylet;
|
||||
using System;
|
||||
using Stylet;
|
||||
|
||||
namespace DiscordChatExporter.Gui.ViewModels.Framework
|
||||
{
|
||||
public abstract class DialogScreen<T> : Screen
|
||||
public abstract class DialogScreen<T> : PropertyChangedBase
|
||||
{
|
||||
public T DialogResult { get; private set; }
|
||||
|
||||
public event EventHandler? Closed;
|
||||
|
||||
public void Close(T dialogResult = default)
|
||||
{
|
||||
// Set the result
|
||||
DialogResult = dialogResult;
|
||||
|
||||
// If there is a parent - ask them to close this dialog
|
||||
if (Parent != null)
|
||||
RequestClose(Equals(dialogResult, default(T)));
|
||||
// Otherwise close ourselves
|
||||
else
|
||||
((IScreenState) this).Close();
|
||||
Closed?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@ namespace DiscordChatExporter.Gui.ViewModels.Framework
|
|||
{
|
||||
public static class Extensions
|
||||
{
|
||||
public static ChannelViewModel CreateChannelViewModel(this IViewModelFactory factory, Channel model,
|
||||
string category = null)
|
||||
public static ChannelViewModel CreateChannelViewModel(this IViewModelFactory factory, Channel model, string? category = null)
|
||||
{
|
||||
var viewModel = factory.CreateChannelViewModel();
|
||||
viewModel.Model = model;
|
||||
|
|
|
@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using DiscordChatExporter.Core.Models;
|
||||
using DiscordChatExporter.Core.Services;
|
||||
|
@ -38,13 +37,13 @@ namespace DiscordChatExporter.Gui.ViewModels
|
|||
|
||||
public bool IsBotToken { get; set; }
|
||||
|
||||
public string TokenValue { get; set; }
|
||||
public string? TokenValue { get; set; }
|
||||
|
||||
public IReadOnlyList<GuildViewModel> AvailableGuilds { get; private set; }
|
||||
public IReadOnlyList<GuildViewModel>? AvailableGuilds { get; private set; }
|
||||
|
||||
public GuildViewModel SelectedGuild { get; set; }
|
||||
public GuildViewModel? SelectedGuild { get; set; }
|
||||
|
||||
public IReadOnlyList<ChannelViewModel> SelectedChannels { get; set; }
|
||||
public IReadOnlyList<ChannelViewModel>? SelectedChannels { get; set; }
|
||||
|
||||
public RootViewModel(IViewModelFactory viewModelFactory, DialogManager dialogManager,
|
||||
SettingsService settingsService, UpdateService updateService, DataService dataService,
|
||||
|
@ -58,8 +57,7 @@ namespace DiscordChatExporter.Gui.ViewModels
|
|||
_exportService = exportService;
|
||||
|
||||
// Set title
|
||||
var version = Assembly.GetExecutingAssembly().GetName().Version.ToString(3);
|
||||
DisplayName = $"DiscordChatExporter v{version}";
|
||||
DisplayName = $"{App.Name} v{App.VersionString}";
|
||||
|
||||
// Update busy state when progress manager changes
|
||||
ProgressManager.Bind(o => o.IsActive, (sender, args) => IsBusy = ProgressManager.IsActive);
|
||||
|
@ -83,7 +81,7 @@ namespace DiscordChatExporter.Gui.ViewModels
|
|||
return;
|
||||
|
||||
// Notify user of an update and prepare it
|
||||
Notifications.Enqueue($"Downloading update to DiscordChatExporter v{updateVersion}...");
|
||||
Notifications.Enqueue($"Downloading update to {App.Name} v{updateVersion}...");
|
||||
await _updateService.PrepareUpdateAsync(updateVersion);
|
||||
|
||||
// Prompt user to install update (otherwise install it when application exits)
|
||||
|
@ -140,7 +138,7 @@ namespace DiscordChatExporter.Gui.ViewModels
|
|||
await _dialogManager.ShowDialogAsync(dialog);
|
||||
}
|
||||
|
||||
public bool CanPopulateGuildsAndChannels => !IsBusy && !TokenValue.IsNullOrWhiteSpace();
|
||||
public bool CanPopulateGuildsAndChannels => !IsBusy && !string.IsNullOrWhiteSpace(TokenValue);
|
||||
|
||||
public async void PopulateGuildsAndChannels()
|
||||
{
|
||||
|
@ -150,7 +148,7 @@ namespace DiscordChatExporter.Gui.ViewModels
|
|||
try
|
||||
{
|
||||
// Sanitize token
|
||||
TokenValue = TokenValue.Trim('"');
|
||||
TokenValue = TokenValue!.Trim('"');
|
||||
|
||||
// Create token
|
||||
var token = new AuthToken(
|
||||
|
@ -253,15 +251,15 @@ namespace DiscordChatExporter.Gui.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
public bool CanExportChannels => !IsBusy && !SelectedChannels.IsNullOrEmpty();
|
||||
public bool CanExportChannels => !IsBusy && SelectedGuild != null && SelectedChannels != null && SelectedChannels.Any();
|
||||
|
||||
public async void ExportChannels()
|
||||
{
|
||||
// Get last used token
|
||||
var token = _settingsService.LastToken;
|
||||
var token = _settingsService.LastToken!;
|
||||
|
||||
// Create dialog
|
||||
var dialog = _viewModelFactory.CreateExportSetupViewModel(SelectedGuild, SelectedChannels);
|
||||
var dialog = _viewModelFactory.CreateExportSetupViewModel(SelectedGuild!, SelectedChannels!);
|
||||
|
||||
// Show dialog, if canceled - return
|
||||
if (await _dialogManager.ShowDialogAsync(dialog) != true)
|
||||
|
@ -281,7 +279,7 @@ namespace DiscordChatExporter.Gui.ViewModels
|
|||
try
|
||||
{
|
||||
// Generate file path if necessary
|
||||
var filePath = dialog.OutputPath;
|
||||
var filePath = dialog.OutputPath!;
|
||||
if (ExportHelper.IsDirectoryPath(filePath))
|
||||
{
|
||||
// Generate default file name
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue