Streamline auto-update process and refactor

pull/236/head
Alexey Golub 5 years ago
parent 82af36c90d
commit 12a5091d73

@ -9,8 +9,6 @@ namespace DiscordChatExporter.Gui.Services
{
public class UpdateService : IDisposable
{
private readonly SettingsService _settingsService;
private readonly IUpdateManager _updateManager = new UpdateManager(
new GithubPackageResolver("Tyrrrz", "DiscordChatExporter", "DiscordChatExporter.zip"),
new ZipPackageExtractor());
@ -18,36 +16,25 @@ namespace DiscordChatExporter.Gui.Services
private Version _updateVersion;
private bool _updaterLaunched;
public UpdateService(SettingsService settingsService)
public async Task<Version> CheckForUpdatesAsync()
{
_settingsService = settingsService;
var check = await _updateManager.CheckForUpdatesAsync();
return check.CanUpdate ? check.LastVersion : null;
}
public async Task<Version> CheckPrepareUpdateAsync()
public async Task PrepareUpdateAsync(Version version)
{
try
{
// If auto-update is disabled - don't check for updates
if (!_settingsService.IsAutoUpdateEnabled)
return null;
// Check for updates
var check = await _updateManager.CheckForUpdatesAsync();
if (!check.CanUpdate)
return null;
// Prepare the update
await _updateManager.PrepareUpdateAsync(check.LastVersion);
return _updateVersion = check.LastVersion;
await _updateManager.PrepareUpdateAsync(_updateVersion = version);
}
catch (UpdaterAlreadyLaunchedException)
{
return null;
// Ignore race conditions
}
catch (LockFileNotAcquiredException)
{
return null;
// Ignore race conditions
}
}
@ -55,23 +42,20 @@ namespace DiscordChatExporter.Gui.Services
{
try
{
// Check if an update is pending
if (_updateVersion == null)
if (_updateVersion == null || _updaterLaunched)
return;
// Check if the updater has already been launched
if (_updaterLaunched)
return;
// Launch the updater
_updateManager.LaunchUpdater(_updateVersion, needRestart);
_updaterLaunched = true;
}
catch (UpdaterAlreadyLaunchedException)
{
// Ignore race conditions
}
catch (LockFileNotAcquiredException)
{
// Ignore race conditions
}
}

@ -22,46 +22,46 @@ namespace DiscordChatExporter.Gui.ViewModels.Framework
var view = _viewManager.CreateAndBindViewForModelIfNecessary(dialogScreen);
// Set up event routing that will close the view when called from viewmodel
DialogOpenedEventHandler onDialogOpened = (sender, e) =>
void OnDialogOpened(object sender, DialogOpenedEventArgs openArgs)
{
// Delegate to close the dialog and unregister event handler
void OnScreenClosed(object o, CloseEventArgs args)
void OnScreenClosed(object o, CloseEventArgs closeArgs)
{
e.Session.Close();
openArgs.Session.Close();
dialogScreen.Closed -= OnScreenClosed;
}
dialogScreen.Closed += OnScreenClosed;
};
}
// Show view
await DialogHost.Show(view, onDialogOpened);
await DialogHost.Show(view, OnDialogOpened);
// Return the result
return dialogScreen.DialogResult;
}
public string PromptSaveFilePath(string filter = "All files|*.*", string initialFilePath = "")
public string PromptSaveFilePath(string filter = "All files|*.*", string defaultFilePath = "")
{
// Create dialog
var dialog = new SaveFileDialog
{
Filter = filter,
AddExtension = true,
FileName = initialFilePath,
DefaultExt = Path.GetExtension(initialFilePath) ?? ""
FileName = defaultFilePath,
DefaultExt = Path.GetExtension(defaultFilePath) ?? ""
};
// Show dialog and return result
return dialog.ShowDialog() == true ? dialog.FileName : null;
}
public string PromptDirectoryPath(string initialDirPath = "")
public string PromptDirectoryPath(string defaultDirPath = "")
{
// Create dialog
var dialog = new VistaFolderBrowserDialog
{
SelectedPath = initialDirPath
SelectedPath = defaultDirPath
};
// Show dialog and return result

@ -36,9 +36,5 @@ namespace DiscordChatExporter.Gui.ViewModels.Framework
return viewModel;
}
public static ExportSetupViewModel CreateExportSetupViewModel(this IViewModelFactory factory,
GuildViewModel guild, ChannelViewModel channel)
=> factory.CreateExportSetupViewModel(guild, new[] { channel });
}
}

@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Threading.Tasks;
using DiscordChatExporter.Core.Models;
using DiscordChatExporter.Core.Services;
using DiscordChatExporter.Core.Services.Exceptions;
@ -68,6 +69,39 @@ namespace DiscordChatExporter.Gui.ViewModels
(sender, args) => IsProgressIndeterminate = ProgressManager.IsActive && ProgressManager.Progress.IsEither(0, 1));
}
private async Task HandleAutoUpdateAsync()
{
try
{
// Don't check for updates if auto-update is disabled
if (!_settingsService.IsAutoUpdateEnabled)
return;
// Check for updates
var updateVersion = await _updateService.CheckForUpdatesAsync();
if (updateVersion == null)
return;
// Notify user of an update and prepare it
Notifications.Enqueue($"Downloading update to DiscordChatExporter v{updateVersion}...");
await _updateService.PrepareUpdateAsync(updateVersion);
// Prompt user to install update (otherwise install it when application exits)
Notifications.Enqueue(
"Update has been downloaded and will be installed when you exit",
"INSTALL NOW", () =>
{
_updateService.FinalizeUpdate(true);
RequestClose();
});
}
catch
{
// Failure to update shouldn't crash the application
Notifications.Enqueue("Failed to perform application update");
}
}
protected override async void OnViewLoaded()
{
base.OnViewLoaded();
@ -83,24 +117,7 @@ namespace DiscordChatExporter.Gui.ViewModels
}
// Check and prepare update
try
{
var updateVersion = await _updateService.CheckPrepareUpdateAsync();
if (updateVersion != null)
{
Notifications.Enqueue(
$"Update to DiscordChatExporter v{updateVersion} will be installed when you exit",
"INSTALL NOW", () =>
{
_updateService.FinalizeUpdate(true);
RequestClose();
});
}
}
catch
{
Notifications.Enqueue("Failed to perform application auto-update");
}
await HandleAutoUpdateAsync();
}
protected override void OnClose()

Loading…
Cancel
Save