diff --git a/DiscordChatExporter.Cli/Container.cs b/DiscordChatExporter.Cli/Container.cs index 164e3b51..0120cfb0 100644 --- a/DiscordChatExporter.Cli/Container.cs +++ b/DiscordChatExporter.Cli/Container.cs @@ -1,7 +1,7 @@ -using DiscordChatExporter.Cli.ViewModels; +using CommonServiceLocator; +using DiscordChatExporter.Cli.ViewModels; using DiscordChatExporter.Core.Services; using GalaSoft.MvvmLight.Ioc; -using Microsoft.Practices.ServiceLocation; namespace DiscordChatExporter.Cli { diff --git a/DiscordChatExporter.Cli/DiscordChatExporter.Cli.csproj b/DiscordChatExporter.Cli/DiscordChatExporter.Cli.csproj index 98d78007..6d9492ad 100644 --- a/DiscordChatExporter.Cli/DiscordChatExporter.Cli.csproj +++ b/DiscordChatExporter.Cli/DiscordChatExporter.Cli.csproj @@ -10,9 +10,9 @@ - + - + diff --git a/DiscordChatExporter.Core/DiscordChatExporter.Core.csproj b/DiscordChatExporter.Core/DiscordChatExporter.Core.csproj index 76d1a188..7c070181 100644 --- a/DiscordChatExporter.Core/DiscordChatExporter.Core.csproj +++ b/DiscordChatExporter.Core/DiscordChatExporter.Core.csproj @@ -15,7 +15,7 @@ - + diff --git a/DiscordChatExporter.Core/Services/IUpdateService.cs b/DiscordChatExporter.Core/Services/IUpdateService.cs index e79feb8f..ded18f5e 100644 --- a/DiscordChatExporter.Core/Services/IUpdateService.cs +++ b/DiscordChatExporter.Core/Services/IUpdateService.cs @@ -5,10 +5,10 @@ namespace DiscordChatExporter.Core.Services { public interface IUpdateService { - Task CheckForUpdatesAsync(); + bool NeedRestart { get; set; } - Task PrepareUpdateAsync(); + Task CheckPrepareUpdateAsync(); - Task ApplyUpdateAsync(bool restart = true); + Task FinalizeUpdateAsync(); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Services/UpdateService.cs b/DiscordChatExporter.Core/Services/UpdateService.cs index 7a8a6030..57de55ff 100644 --- a/DiscordChatExporter.Core/Services/UpdateService.cs +++ b/DiscordChatExporter.Core/Services/UpdateService.cs @@ -8,82 +8,55 @@ namespace DiscordChatExporter.Core.Services public class UpdateService : IUpdateService { private readonly ISettingsService _settingsService; - private readonly UpdateManager _updateManager; + private readonly IUpdateManager _manager; - private Version _lastVersion; - private bool _applied; + private Version _updateVersion; + private bool _updateFinalized; + + public bool NeedRestart { get; set; } public UpdateService(ISettingsService settingsService) { _settingsService = settingsService; - _updateManager = new UpdateManager( + _manager = new UpdateManager( new GithubPackageResolver("Tyrrrz", "DiscordChatExporter", "DiscordChatExporter.zip"), new ZipPackageExtractor()); } - public async Task CheckForUpdatesAsync() + public async Task CheckPrepareUpdateAsync() { -#if DEBUG - // Never update in DEBUG mode - return null; -#endif - - // Don't update if user disabled it + // If auto-update is disabled - don't check for updates if (!_settingsService.IsAutoUpdateEnabled) return null; - try - { - // Remove some junk left over from last update - _updateManager.Cleanup(); + // Cleanup leftover files + _manager.Cleanup(); - // Check for updates - var check = await _updateManager.CheckForUpdatesAsync(); - - // Return latest version or null if running latest version already - return check.CanUpdate ? _lastVersion = check.LastVersion : null; - } - catch - { - // It's okay for update to fail + // Check for updates + var check = await _manager.CheckForUpdatesAsync(); + if (!check.CanUpdate) return null; - } + + // Prepare the update + await _manager.PrepareUpdateAsync(check.LastVersion); + + return _updateVersion = check.LastVersion; } - public async Task PrepareUpdateAsync() + public async Task FinalizeUpdateAsync() { - if (_lastVersion == null) + // Check if an update is pending + if (_updateVersion == null) return; - try - { - // Download and prepare update - await _updateManager.PreparePackageAsync(_lastVersion); - } - catch - { - // It's okay for update to fail - } - } - - public async Task ApplyUpdateAsync(bool restart = true) - { - if (_lastVersion == null) - return; - if (_applied) + // Check if the update has already been finalized + if (_updateFinalized) return; - try - { - // Enqueue an update - await _updateManager.EnqueueApplyPackageAsync(_lastVersion, restart); - _applied = true; - } - catch - { - // It's okay for update to fail - } + // Launch the updater + await _manager.LaunchUpdaterAsync(_updateVersion, NeedRestart); + _updateFinalized = true; } } } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/Container.cs b/DiscordChatExporter.Gui/Container.cs index b46cf987..6ed5089b 100644 --- a/DiscordChatExporter.Gui/Container.cs +++ b/DiscordChatExporter.Gui/Container.cs @@ -1,7 +1,7 @@ -using DiscordChatExporter.Core.Services; +using CommonServiceLocator; +using DiscordChatExporter.Core.Services; using DiscordChatExporter.Gui.ViewModels; using GalaSoft.MvvmLight.Ioc; -using Microsoft.Practices.ServiceLocation; namespace DiscordChatExporter.Gui { diff --git a/DiscordChatExporter.Gui/DiscordChatExporter.Gui.csproj b/DiscordChatExporter.Gui/DiscordChatExporter.Gui.csproj index 6285d185..5944064e 100644 --- a/DiscordChatExporter.Gui/DiscordChatExporter.Gui.csproj +++ b/DiscordChatExporter.Gui/DiscordChatExporter.Gui.csproj @@ -45,28 +45,28 @@ ..\packages\Ammy.WPF.1.2.94\lib\net40\AmmySidekick.dll - - ..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.dll + + ..\packages\CommonServiceLocator.2.0.3\lib\net45\CommonServiceLocator.dll - - ..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.Extras.dll + + ..\packages\MvvmLightLibs.5.4.1\lib\net45\GalaSoft.MvvmLight.dll - - ..\packages\MvvmLightLibs.5.3.0.0\lib\net45\GalaSoft.MvvmLight.Platform.dll + + ..\packages\MvvmLightLibs.5.4.1\lib\net45\GalaSoft.MvvmLight.Extras.dll + + + ..\packages\MvvmLightLibs.5.4.1\lib\net45\GalaSoft.MvvmLight.Platform.dll ..\packages\MaterialDesignColors.1.1.3\lib\net45\MaterialDesignColors.dll - - ..\packages\MaterialDesignThemes.2.3.1.953\lib\net45\MaterialDesignThemes.Wpf.dll - - - ..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll + + ..\packages\MaterialDesignThemes.2.4.0.1044\lib\net45\MaterialDesignThemes.Wpf.dll - ..\packages\MvvmLightLibs.5.3.0.0\lib\net45\System.Windows.Interactivity.dll + ..\packages\MvvmLightLibs.5.4.1\lib\net45\System.Windows.Interactivity.dll 4.0 @@ -74,6 +74,7 @@ ..\packages\Tyrrrz.Extensions.1.5.0\lib\net45\Tyrrrz.Extensions.dll + @@ -146,6 +147,7 @@ Resources.Designer.cs + Designer diff --git a/DiscordChatExporter.Gui/ViewModels/MainViewModel.cs b/DiscordChatExporter.Gui/ViewModels/MainViewModel.cs index 47ea8e5d..f9703401 100644 --- a/DiscordChatExporter.Gui/ViewModels/MainViewModel.cs +++ b/DiscordChatExporter.Gui/ViewModels/MainViewModel.cs @@ -111,7 +111,7 @@ namespace DiscordChatExporter.Gui.ViewModels // Messages MessengerInstance.Register(this, - m => { Export(m.Channel, m.FilePath, m.Format, m.From, m.To); }); + m => Export(m.Channel, m.FilePath, m.Format, m.From, m.To)); } private async void ViewLoaded() @@ -122,33 +122,34 @@ namespace DiscordChatExporter.Gui.ViewModels // Set last token Token = _settingsService.LastToken; - // Check for updates - var lastVersion = await _updateService.CheckForUpdatesAsync(); - if (lastVersion != null) + // Check and prepare update + try { - // Download updates - await _updateService.PrepareUpdateAsync(); - - // Notify user - MessengerInstance.Send( - new ShowNotificationMessage( - $"DiscordChatExporter v{lastVersion} has been downloaded – it will be installed when you exit", - "INSTALL NOW", - async () => + var updateVersion = await _updateService.CheckPrepareUpdateAsync(); + if (updateVersion != null) + { + MessengerInstance.Send(new ShowNotificationMessage( + $"Update to DiscordChatExporter v{updateVersion} will be installed when you exit", + "INSTALL NOW", () => { - await _updateService.ApplyUpdateAsync(); + _updateService.NeedRestart = true; Application.Current.Shutdown(); })); + } + } + catch + { + MessengerInstance.Send(new ShowNotificationMessage("Failed to perform application auto-update")); } } - private void ViewClosed() + private async void ViewClosed() { // Save settings _settingsService.Save(); - // Apply updates if available - _updateService.ApplyUpdateAsync(false); + // Finalize updates if available + await _updateService.FinalizeUpdateAsync(); } private async void PullData() @@ -185,13 +186,11 @@ namespace DiscordChatExporter.Gui.ViewModels } catch (HttpErrorStatusCodeException ex) when (ex.StatusCode == HttpStatusCode.Unauthorized) { - const string message = "Unauthorized – make sure the token is valid"; - MessengerInstance.Send(new ShowNotificationMessage(message)); + MessengerInstance.Send(new ShowNotificationMessage("Unauthorized – make sure the token is valid")); } catch (HttpErrorStatusCodeException ex) when (ex.StatusCode == HttpStatusCode.Forbidden) { - const string message = "Forbidden – account may be locked by 2FA"; - MessengerInstance.Send(new ShowNotificationMessage(message)); + MessengerInstance.Send(new ShowNotificationMessage("Forbidden – account may be locked by 2FA")); } AvailableGuilds = _guildChannelsMap.Keys.ToArray(); @@ -237,13 +236,11 @@ namespace DiscordChatExporter.Gui.ViewModels // Notify completion MessengerInstance.Send(new ShowNotificationMessage($"Export completed for channel [{channel.Name}]", - "OPEN", - () => Process.Start(filePath))); + "OPEN", () => Process.Start(filePath))); } catch (HttpErrorStatusCodeException ex) when (ex.StatusCode == HttpStatusCode.Forbidden) { - const string message = "You don't have access to that channel"; - MessengerInstance.Send(new ShowNotificationMessage(message)); + MessengerInstance.Send(new ShowNotificationMessage("You don't have access to that channel")); } IsBusy = false; diff --git a/DiscordChatExporter.Gui/Views/MainWindow.ammy.cs b/DiscordChatExporter.Gui/Views/MainWindow.ammy.cs index cc269e4d..c51579de 100644 --- a/DiscordChatExporter.Gui/Views/MainWindow.ammy.cs +++ b/DiscordChatExporter.Gui/Views/MainWindow.ammy.cs @@ -17,13 +17,18 @@ namespace DiscordChatExporter.Gui.Views Snackbar.MessageQueue = new SnackbarMessageQueue(TimeSpan.FromSeconds(5)); // Notification messages - Messenger.Default.Register(this, - m => Snackbar.MessageQueue.Enqueue(m.Message, m.CallbackCaption, m.Callback)); + Messenger.Default.Register(this, m => + { + if (m.CallbackCaption != null && m.Callback != null) + Snackbar.MessageQueue.Enqueue(m.Message, m.CallbackCaption, m.Callback); + else + Snackbar.MessageQueue.Enqueue(m.Message); + }); // Dialog messages Messenger.Default.Register(this, m => DialogHost.Show(new ExportSetupDialog()).Forget()); - Messenger.Default.Register(this, + Messenger.Default.Register(this, m => DialogHost.Show(new SettingsDialog()).Forget()); } } diff --git a/DiscordChatExporter.Gui/app.config b/DiscordChatExporter.Gui/app.config new file mode 100644 index 00000000..9a1a9fa2 --- /dev/null +++ b/DiscordChatExporter.Gui/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/DiscordChatExporter.Gui/packages.config b/DiscordChatExporter.Gui/packages.config index 144d4245..ffcabf45 100644 --- a/DiscordChatExporter.Gui/packages.config +++ b/DiscordChatExporter.Gui/packages.config @@ -2,9 +2,9 @@ - + - - + + \ No newline at end of file