mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-05-27 21:24:12 -04:00
Implement auto-update via Onova
This commit is contained in:
parent
7bfd645e8e
commit
63c835df88
11 changed files with 187 additions and 22 deletions
|
@ -14,7 +14,8 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.1" />
|
||||
<PackageReference Include="Onova" Version="1.0.0" />
|
||||
<PackageReference Include="Tyrrrz.Extensions" Version="1.5.0" />
|
||||
<PackageReference Include="Tyrrrz.Settings" Version="1.3.2" />
|
||||
</ItemGroup>
|
||||
|
|
14
DiscordChatExporter.Core/Services/IUpdateService.cs
Normal file
14
DiscordChatExporter.Core/Services/IUpdateService.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DiscordChatExporter.Core.Services
|
||||
{
|
||||
public interface IUpdateService
|
||||
{
|
||||
Task<Version> CheckForUpdatesAsync();
|
||||
|
||||
Task PrepareUpdateAsync();
|
||||
|
||||
Task ApplyUpdateAsync(bool restart = true);
|
||||
}
|
||||
}
|
61
DiscordChatExporter.Core/Services/UpdateService.cs
Normal file
61
DiscordChatExporter.Core/Services/UpdateService.cs
Normal file
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Onova;
|
||||
using Onova.Services;
|
||||
|
||||
namespace DiscordChatExporter.Core.Services
|
||||
{
|
||||
public class UpdateService : IUpdateService
|
||||
{
|
||||
private readonly UpdateManager _updateManager;
|
||||
|
||||
private Version _lastVersion;
|
||||
private bool _applied;
|
||||
|
||||
public UpdateService()
|
||||
{
|
||||
_updateManager = new UpdateManager(
|
||||
new GithubPackageResolver("Tyrrrz", "DiscordChatExporter", "DiscordChatExporter.zip"),
|
||||
new ZipPackageExtractor());
|
||||
}
|
||||
|
||||
public async Task<Version> CheckForUpdatesAsync()
|
||||
{
|
||||
#if DEBUG
|
||||
// Never update in DEBUG mode
|
||||
return null;
|
||||
#endif
|
||||
|
||||
// Remove some junk left over from last update
|
||||
_updateManager.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;
|
||||
}
|
||||
|
||||
public async Task PrepareUpdateAsync()
|
||||
{
|
||||
if (_lastVersion == null)
|
||||
return;
|
||||
|
||||
// Download and prepare update
|
||||
await _updateManager.PreparePackageAsync(_lastVersion);
|
||||
}
|
||||
|
||||
public async Task ApplyUpdateAsync(bool restart = true)
|
||||
{
|
||||
if (_lastVersion == null)
|
||||
return;
|
||||
if (_applied)
|
||||
return;
|
||||
|
||||
// Enqueue an update
|
||||
await _updateManager.EnqueueApplyPackageAsync(_lastVersion, restart);
|
||||
|
||||
_applied = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,9 +28,7 @@ namespace DiscordChatExporter.Gui
|
|||
SimpleIoc.Default.Register<IExportService, ExportService>();
|
||||
SimpleIoc.Default.Register<IMessageGroupService, MessageGroupService>();
|
||||
SimpleIoc.Default.Register<ISettingsService, SettingsService>();
|
||||
|
||||
// Load settings
|
||||
Resolve<ISettingsService>().Load();
|
||||
SimpleIoc.Default.Register<IUpdateService, UpdateService>();
|
||||
|
||||
// View models
|
||||
SimpleIoc.Default.Register<IErrorViewModel, ErrorViewModel>(true);
|
||||
|
@ -42,8 +40,6 @@ namespace DiscordChatExporter.Gui
|
|||
|
||||
public void Cleanup()
|
||||
{
|
||||
// Save settings
|
||||
ServiceLocator.Current.GetInstance<ISettingsService>().Save();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,14 +65,12 @@
|
|||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MvvmLightLibs.5.3.0.0\lib\net45\System.Windows.Interactivity.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xaml">
|
||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Tyrrrz.Extensions, Version=1.5.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Tyrrrz.Extensions.1.5.0\lib\net45\Tyrrrz.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -84,6 +82,7 @@
|
|||
<Compile Include="Messages\ShowErrorMessage.cs" />
|
||||
<Compile Include="Messages\ShowExportDoneMessage.cs" />
|
||||
<Compile Include="Messages\ShowExportSetupMessage.cs" />
|
||||
<Compile Include="Messages\ShowNotificationMessage.cs" />
|
||||
<Compile Include="Messages\ShowSettingsMessage.cs" />
|
||||
<Compile Include="Messages\StartExportMessage.cs" />
|
||||
<Compile Include="ViewModels\ErrorViewModel.cs" />
|
||||
|
|
25
DiscordChatExporter.Gui/Messages/ShowNotificationMessage.cs
Normal file
25
DiscordChatExporter.Gui/Messages/ShowNotificationMessage.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
|
||||
namespace DiscordChatExporter.Gui.Messages
|
||||
{
|
||||
public class ShowNotificationMessage
|
||||
{
|
||||
public string Message { get; }
|
||||
|
||||
public string CallbackCaption { get; }
|
||||
|
||||
public Action Callback { get; }
|
||||
|
||||
public ShowNotificationMessage(string message)
|
||||
{
|
||||
Message = message;
|
||||
}
|
||||
|
||||
public ShowNotificationMessage(string message, string callbackCaption, Action callback)
|
||||
: this(message)
|
||||
{
|
||||
CallbackCaption = callbackCaption;
|
||||
Callback = callback;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,6 +15,8 @@ namespace DiscordChatExporter.Gui.ViewModels
|
|||
Guild SelectedGuild { get; set; }
|
||||
IReadOnlyList<Channel> AvailableChannels { get; }
|
||||
|
||||
RelayCommand ViewLoadedCommand { get; }
|
||||
RelayCommand ViewClosedCommand { get; }
|
||||
RelayCommand PullDataCommand { get; }
|
||||
RelayCommand ShowSettingsCommand { get; }
|
||||
RelayCommand ShowAboutCommand { get; }
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Windows;
|
||||
using DiscordChatExporter.Core.Exceptions;
|
||||
using DiscordChatExporter.Core.Models;
|
||||
using DiscordChatExporter.Core.Services;
|
||||
|
@ -16,6 +17,7 @@ namespace DiscordChatExporter.Gui.ViewModels
|
|||
public class MainViewModel : ViewModelBase, IMainViewModel
|
||||
{
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IUpdateService _updateService;
|
||||
private readonly IDataService _dataService;
|
||||
private readonly IMessageGroupService _messageGroupService;
|
||||
private readonly IExportService _exportService;
|
||||
|
@ -81,15 +83,18 @@ namespace DiscordChatExporter.Gui.ViewModels
|
|||
private set => Set(ref _availableChannels, value);
|
||||
}
|
||||
|
||||
public RelayCommand ViewLoadedCommand { get; }
|
||||
public RelayCommand ViewClosedCommand { get; }
|
||||
public RelayCommand PullDataCommand { get; }
|
||||
public RelayCommand ShowSettingsCommand { get; }
|
||||
public RelayCommand ShowAboutCommand { get; }
|
||||
public RelayCommand<Channel> ShowExportSetupCommand { get; }
|
||||
|
||||
public MainViewModel(ISettingsService settingsService, IDataService dataService,
|
||||
public MainViewModel(ISettingsService settingsService, IUpdateService updateService, IDataService dataService,
|
||||
IMessageGroupService messageGroupService, IExportService exportService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_updateService = updateService;
|
||||
_dataService = dataService;
|
||||
_messageGroupService = messageGroupService;
|
||||
_exportService = exportService;
|
||||
|
@ -97,19 +102,54 @@ namespace DiscordChatExporter.Gui.ViewModels
|
|||
_guildChannelsMap = new Dictionary<Guild, IReadOnlyList<Channel>>();
|
||||
|
||||
// Commands
|
||||
ViewLoadedCommand = new RelayCommand(ViewLoaded);
|
||||
ViewClosedCommand = new RelayCommand(ViewClosed);
|
||||
PullDataCommand = new RelayCommand(PullData, () => Token.IsNotBlank() && !IsBusy);
|
||||
ShowSettingsCommand = new RelayCommand(ShowSettings);
|
||||
ShowAboutCommand = new RelayCommand(ShowAbout);
|
||||
ShowExportSetupCommand = new RelayCommand<Channel>(ShowExportSetup, _ => !IsBusy);
|
||||
|
||||
// Messages
|
||||
MessengerInstance.Register<StartExportMessage>(this, m =>
|
||||
{
|
||||
Export(m.Channel, m.FilePath, m.Format, m.From, m.To);
|
||||
});
|
||||
MessengerInstance.Register<StartExportMessage>(this,
|
||||
m => { Export(m.Channel, m.FilePath, m.Format, m.From, m.To); });
|
||||
}
|
||||
|
||||
// Defaults
|
||||
_token = _settingsService.LastToken;
|
||||
private async void ViewLoaded()
|
||||
{
|
||||
// Load settings
|
||||
_settingsService.Load();
|
||||
|
||||
// Set last token
|
||||
Token = _settingsService.LastToken;
|
||||
|
||||
// Check for updates
|
||||
var lastVersion = await _updateService.CheckForUpdatesAsync();
|
||||
if (lastVersion != null)
|
||||
{
|
||||
// Download updates
|
||||
await _updateService.PrepareUpdateAsync();
|
||||
|
||||
// Notify user
|
||||
MessengerInstance.Send(
|
||||
new ShowNotificationMessage(
|
||||
$"DiscordChatExporter v{lastVersion} has been downloaded. " +
|
||||
"It will be installed once you exit.",
|
||||
"INSTALL NOW",
|
||||
async () =>
|
||||
{
|
||||
await _updateService.ApplyUpdateAsync();
|
||||
Application.Current.Shutdown();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private void ViewClosed()
|
||||
{
|
||||
// Save settings
|
||||
_settingsService.Save();
|
||||
|
||||
// Apply updates if available
|
||||
_updateService.ApplyUpdateAsync(false);
|
||||
}
|
||||
|
||||
private async void PullData()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MaterialDesignThemes.Wpf
|
||||
using System.Windows.Interactivity;
|
||||
using MaterialDesignThemes.Wpf
|
||||
using MaterialDesignThemes.Wpf.Transitions
|
||||
|
||||
Window "DiscordChatExporter.Gui.Views.MainWindow" {
|
||||
|
@ -19,15 +20,27 @@ Window "DiscordChatExporter.Gui.Views.MainWindow" {
|
|||
UseLayoutRounding: true
|
||||
WindowStartupLocation: CenterScreen
|
||||
|
||||
DialogHost {
|
||||
DockPanel {
|
||||
IsEnabled: bind IsBusy
|
||||
convert (bool b) => b ? false : true
|
||||
Interaction.Triggers: [
|
||||
Interactivity.EventTrigger {
|
||||
EventName: "Loaded"
|
||||
InvokeCommandAction { Command: bind ViewLoadedCommand }
|
||||
},
|
||||
Interactivity.EventTrigger {
|
||||
EventName: "Closed"
|
||||
InvokeCommandAction { Command: bind ViewClosedCommand }
|
||||
}
|
||||
]
|
||||
|
||||
DialogHost {
|
||||
SnackbarMessageQueue: bind MessageQueue from "Snackbar"
|
||||
|
||||
DockPanel {
|
||||
// Toolbar
|
||||
Border {
|
||||
DockPanel.Dock: Top
|
||||
Background: resource dyn "PrimaryHueMidBrush"
|
||||
IsEnabled: bind IsBusy
|
||||
convert (bool b) => b ? false : true
|
||||
TextElement.Foreground: resource dyn "SecondaryInverseTextBrush"
|
||||
StackPanel {
|
||||
Grid {
|
||||
|
@ -104,6 +117,8 @@ Window "DiscordChatExporter.Gui.Views.MainWindow" {
|
|||
Grid {
|
||||
DockPanel {
|
||||
Background: resource dyn "MaterialDesignCardBackground"
|
||||
IsEnabled: bind IsBusy
|
||||
convert (bool b) => b ? false : true
|
||||
Visibility: bind IsDataAvailable
|
||||
convert (bool b) => b ? Visibility.Visible : Visibility.Hidden
|
||||
|
||||
|
@ -265,6 +280,10 @@ Window "DiscordChatExporter.Gui.Views.MainWindow" {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Snackbar
|
||||
Snackbar "Snackbar" {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Reflection;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using DiscordChatExporter.Gui.Messages;
|
||||
using GalaSoft.MvvmLight.Messaging;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
|
@ -13,7 +14,13 @@ namespace DiscordChatExporter.Gui.Views
|
|||
InitializeComponent();
|
||||
Title += $" v{Assembly.GetExecutingAssembly().GetName().Version}";
|
||||
|
||||
// Dialogs
|
||||
Snackbar.MessageQueue = new SnackbarMessageQueue(TimeSpan.FromSeconds(5));
|
||||
|
||||
// Notification messages
|
||||
Messenger.Default.Register<ShowNotificationMessage>(this,
|
||||
m => Snackbar.MessageQueue.Enqueue(m.Message, m.CallbackCaption, m.Callback));
|
||||
|
||||
// Dialog messages
|
||||
Messenger.Default.Register<ShowErrorMessage>(this,
|
||||
m => DialogHost.Show(new ErrorDialog()).Forget());
|
||||
Messenger.Default.Register<ShowExportDoneMessage>(this,
|
||||
|
|
|
@ -39,6 +39,7 @@ DiscordChatExporter can be used to export message history from a [Discord](https
|
|||
- [GalaSoft.MVVMLight](http://www.mvvmlight.net)
|
||||
- [MaterialDesignInXamlToolkit](https://github.com/ButchersBoy/MaterialDesignInXamlToolkit)
|
||||
- [Newtonsoft.Json](http://www.newtonsoft.com/json)
|
||||
- [Onova](https://github.com/Tyrrrz/Onova)
|
||||
- [FluentCommandLineParser](https://github.com/fclp/fluent-command-line-parser)
|
||||
- [Tyrrrz.Extensions](https://github.com/Tyrrrz/Extensions)
|
||||
- [Tyrrrz.Settings](https://github.com/Tyrrrz/Settings)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue