Add proper Upgrade form
This commit is contained in:
parent
ed15614288
commit
e3b7cbcc2a
@ -29,6 +29,9 @@ namespace AppScaffolding
|
||||
|
||||
public static class LibationScaffolding
|
||||
{
|
||||
public const string RepositoryUrl = "ht" + "tps://github.com/rmcrackan/Libation";
|
||||
public const string WebsiteUrl = "ht" + "tps://getlibation.com";
|
||||
public const string RepositoryLatestUrl = "ht" + "tps://github.com/rmcrackan/Libation/releases/latest";
|
||||
public static ReleaseIdentifier ReleaseIdentifier { get; private set; }
|
||||
public static VarietyType Variety
|
||||
=> ReleaseIdentifier == ReleaseIdentifier.WindowsClassic ? VarietyType.Classic
|
||||
@ -354,7 +357,7 @@ namespace AppScaffolding
|
||||
public static UpgradeProperties GetLatestRelease()
|
||||
{
|
||||
// timed out
|
||||
(var latest, var zip) = getLatestRelease(TimeSpan.FromSeconds(10));
|
||||
(var latest, var zip) = getLatestRelease(TimeSpan.FromSeconds(10000));
|
||||
|
||||
if (latest is null || zip is null)
|
||||
return null;
|
||||
@ -363,9 +366,6 @@ namespace AppScaffolding
|
||||
if (!Version.TryParse(latestVersionString, out var latestRelease))
|
||||
return null;
|
||||
|
||||
// we're up to date
|
||||
if (latestRelease <= BuildVersion)
|
||||
return null;
|
||||
|
||||
// we have an update
|
||||
|
||||
@ -378,7 +378,7 @@ namespace AppScaffolding
|
||||
zipUrl
|
||||
});
|
||||
|
||||
return new(zipUrl, latest.HtmlUrl, zip.Name, latestRelease);
|
||||
return new(zipUrl, latest.HtmlUrl, zip.Name, latestRelease, latest.Body);
|
||||
}
|
||||
private static (Octokit.Release, Octokit.ReleaseAsset) getLatestRelease(TimeSpan timeout)
|
||||
{
|
||||
|
||||
@ -1,6 +1,34 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace AppScaffolding
|
||||
{
|
||||
public record UpgradeProperties(string ZipUrl, string HtmlUrl, string ZipName, Version LatestRelease);
|
||||
public record UpgradeProperties
|
||||
{
|
||||
private static readonly Regex linkstripper = new Regex(@"\[(.*)\]\(.*\)");
|
||||
public string ZipUrl { get; }
|
||||
public string HtmlUrl { get; }
|
||||
public string ZipName { get; }
|
||||
public Version LatestRelease { get; }
|
||||
public string Notes { get; }
|
||||
|
||||
public UpgradeProperties(string zipUrl, string htmlUrl, string zipName, Version latestRelease, string notes)
|
||||
{
|
||||
ZipName = zipName;
|
||||
HtmlUrl = htmlUrl;
|
||||
ZipUrl = zipUrl;
|
||||
LatestRelease = latestRelease;
|
||||
Notes = stripMarkdownLinks(notes);
|
||||
}
|
||||
private string stripMarkdownLinks(string body)
|
||||
{
|
||||
body = body.Replace(@"\", "");
|
||||
var matches = linkstripper.Matches(body);
|
||||
|
||||
foreach (Match match in matches)
|
||||
body = body.Replace(match.Groups[0].Value, match.Groups[1].Value);
|
||||
|
||||
return body;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,54 +0,0 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="350" d:DesignHeight="200"
|
||||
x:Class="LibationAvalonia.Dialogs.UpgradeNotification"
|
||||
xmlns:controls="clr-namespace:LibationAvalonia.Controls"
|
||||
MinWidth="350" MinHeight="200"
|
||||
MaxWidth="350" MaxHeight="200"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Title="Upgrade Available"
|
||||
Icon="/Assets/libation.ico">
|
||||
|
||||
<Grid Margin="6" RowDefinitions="Auto,Auto,Auto,*,Auto">
|
||||
|
||||
<TextBlock Grid.Row="0" FontSize="16" Text="{Binding VersionText}" />
|
||||
|
||||
<controls:LinkLabel
|
||||
Grid.Row="1"
|
||||
Margin="0,10,0,0"
|
||||
Text="{Binding DownloadLinkText}"
|
||||
Tapped="Download_Tapped" />
|
||||
|
||||
<controls:LinkLabel
|
||||
Grid.Row="2"
|
||||
Margin="0,10,0,0"
|
||||
Text="Go to the Libation website"
|
||||
Tapped="Website_Tapped" />
|
||||
|
||||
<controls:LinkLabel
|
||||
Grid.Row="3"
|
||||
Margin="0,10,0,0"
|
||||
Text="View the source code on GitHub"
|
||||
Tapped="Github_Tapped" />
|
||||
|
||||
<Grid Grid.Row="4" ColumnDefinitions="*,Auto">
|
||||
|
||||
<Button
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="Left"
|
||||
Content="Don't remind me
about this release"
|
||||
Click="DontRemind_Click" />
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
TabIndex="0"
|
||||
Padding="20,0,20,0"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalContentAlignment="Center"
|
||||
Content="OK"
|
||||
Click="OK_Click" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
@ -1,42 +0,0 @@
|
||||
using AppScaffolding;
|
||||
using Avalonia.Controls;
|
||||
using Dinah.Core;
|
||||
using System;
|
||||
|
||||
namespace LibationAvalonia.Dialogs
|
||||
{
|
||||
public partial class UpgradeNotification : Window
|
||||
{
|
||||
public string VersionText { get; }
|
||||
public string DownloadLinkText { get; }
|
||||
private string PackageUrl { get; }
|
||||
public UpgradeNotification()
|
||||
{
|
||||
if (Design.IsDesignMode)
|
||||
{
|
||||
VersionText = "Libation version 8.7.0 is now available.";
|
||||
DownloadLinkText = "Download Libation.8.7.0-macos-chardonnay.tar.gz";
|
||||
DataContext = this;
|
||||
}
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public UpgradeNotification(UpgradeProperties upgradeProperties) : this()
|
||||
{
|
||||
VersionText = $"Libation version {upgradeProperties.LatestRelease.ToString(3)} is now available.";
|
||||
PackageUrl = upgradeProperties.ZipUrl;
|
||||
DownloadLinkText = $"Download {upgradeProperties.ZipName}";
|
||||
DataContext = this;
|
||||
}
|
||||
|
||||
public void OK_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e) => Close(DialogResult.OK);
|
||||
public void DontRemind_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e) => Close(DialogResult.Ignore);
|
||||
public void Download_Tapped(object sender, Avalonia.Input.TappedEventArgs e)
|
||||
=> Go.To.Url(PackageUrl);
|
||||
public void Website_Tapped(object sender, Avalonia.Input.TappedEventArgs e)
|
||||
=> Go.To.Url("ht" + "tps://getlibation.com");
|
||||
public void Github_Tapped(object sender, Avalonia.Input.TappedEventArgs e)
|
||||
=> Go.To.Url("ht" + "tps://github.com/rmcrackan/Libation");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="550" d:DesignHeight="450"
|
||||
x:Class="LibationAvalonia.Dialogs.UpgradeNotificationDialog"
|
||||
xmlns:controls="clr-namespace:LibationAvalonia.Controls"
|
||||
MinWidth="500" MinHeight="400"
|
||||
Height="550" Width="450"
|
||||
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Title="Upgrade Available"
|
||||
Icon="/Assets/libation.ico">
|
||||
|
||||
<Grid Margin="6" RowDefinitions="Auto,*,Auto">
|
||||
<TextBlock
|
||||
TextWrapping="WrapWithOverflow"
|
||||
FontSize="15"
|
||||
Text="{Binding TopMessage}"
|
||||
IsVisible="{Binding TopMessage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
||||
|
||||
<controls:GroupBox
|
||||
Grid.Row="1"
|
||||
BorderWidth="2"
|
||||
Label="Release Information"
|
||||
Margin="0,10,0,10">
|
||||
|
||||
<Grid RowDefinitions="*,Auto,Auto">
|
||||
|
||||
<TextBox
|
||||
Grid.Row="0"
|
||||
Margin="0,5,0,10"
|
||||
Grid.ColumnSpan="2"
|
||||
IsReadOnly="true"
|
||||
TextWrapping="WrapWithOverflow"
|
||||
FontSize="12"
|
||||
HorizontalAlignment="Stretch"
|
||||
Text="{Binding ReleaseNotes}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
VerticalAlignment="Bottom"
|
||||
Text="Download Release:" />
|
||||
|
||||
<controls:LinkLabel
|
||||
Grid.Row="1"
|
||||
Margin="0,0,0,10"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
Text="View the source code on GitHub"
|
||||
Tapped="Github_Tapped" />
|
||||
|
||||
<controls:LinkLabel
|
||||
Grid.Row="2"
|
||||
Margin="0,0,0,10"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding DownloadLinkText}"
|
||||
Tapped="Download_Tapped" />
|
||||
|
||||
<controls:LinkLabel
|
||||
Grid.Row="2"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
Text="Go to Libation's website"
|
||||
Tapped="Website_Tapped" />
|
||||
|
||||
</Grid>
|
||||
|
||||
</controls:GroupBox>
|
||||
<Grid
|
||||
Grid.Row="3"
|
||||
ColumnDefinitions="*,Auto">
|
||||
|
||||
<Button
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="Left"
|
||||
Content="Don't remind me
about this release"
|
||||
Click="DontRemind_Click" />
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
TabIndex="0"
|
||||
FontSize="16"
|
||||
Padding="30,0,30,0"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalContentAlignment="Center"
|
||||
Content="{Binding OkText}"
|
||||
Click="OK_Click" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
@ -0,0 +1,51 @@
|
||||
using AppScaffolding;
|
||||
using Avalonia.Controls;
|
||||
using Dinah.Core;
|
||||
using System;
|
||||
|
||||
namespace LibationAvalonia.Dialogs
|
||||
{
|
||||
public partial class UpgradeNotificationDialog : Window
|
||||
{
|
||||
private const string UpdateMessage = "There is a new version available. Would you like to update?\r\n\r\nAfter you close Libation, the upgrade will start automatically.";
|
||||
public string TopMessage { get; }
|
||||
public string DownloadLinkText { get; }
|
||||
public string ReleaseNotes { get; }
|
||||
public string OkText { get; }
|
||||
private string PackageUrl { get; }
|
||||
public UpgradeNotificationDialog()
|
||||
{
|
||||
if (Design.IsDesignMode)
|
||||
{
|
||||
TopMessage = UpdateMessage;
|
||||
Title = "Libation version 8.7.0 is now available.";
|
||||
DownloadLinkText = "Libation.8.7.0-macos-chardonnay.tar.gz";
|
||||
ReleaseNotes = "New features:\r\n\r\n* 'Remove' now removes forever. Removed books won't be re-added on next scan\r\n* #406 : Right Click Menu for Stop-Light Icon\r\n* #398 : Grid, right-click, copy\r\n* Add option for user to choose custom temp folder\r\n* Build Docker image\r\n\r\nEnhancements\r\n\r\n* Illegal Char Replace dialog in Chardonnay\r\n* Filename character replacement allows replacing any char, not just illegal\r\n* #352 : Better error messages for license denial\r\n* Improve 'cancel download'\r\n\r\nThanks to @Mbucari (u/MSWMan), @pixil98 (u/pixil)\r\n\r\nLibation is a free, open source audible library manager for Windows. Decrypt, backup, organize, and search your audible library\r\n\r\nI intend to keep Libation free and open source, but if you want to leave a tip, who am I to argue?";
|
||||
OkText = "Yes";
|
||||
DataContext = this;
|
||||
}
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public UpgradeNotificationDialog(UpgradeProperties upgradeProperties, bool canUpgrade) : this()
|
||||
{
|
||||
Title = $"Libation version {upgradeProperties.LatestRelease.ToString(3)} is now available.";
|
||||
PackageUrl = upgradeProperties.ZipUrl;
|
||||
DownloadLinkText = upgradeProperties.ZipName;
|
||||
ReleaseNotes = upgradeProperties.Notes;
|
||||
TopMessage = canUpgrade ? UpdateMessage : "";
|
||||
OkText = canUpgrade ? "Yes" : "OK";
|
||||
DataContext = this;
|
||||
}
|
||||
|
||||
public void OK_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e) => Close(DialogResult.OK);
|
||||
public void DontRemind_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e) => Close(DialogResult.Ignore);
|
||||
public void Download_Tapped(object sender, Avalonia.Input.TappedEventArgs e)
|
||||
=> Go.To.Url(PackageUrl);
|
||||
public void Website_Tapped(object sender, Avalonia.Input.TappedEventArgs e)
|
||||
=> Go.To.Url(LibationScaffolding.WebsiteUrl);
|
||||
public void Github_Tapped(object sender, Avalonia.Input.TappedEventArgs e)
|
||||
=> Go.To.Url(LibationScaffolding.RepositoryUrl);
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@
|
||||
using LibationAvalonia.Dialogs;
|
||||
using LibationFileManager;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace LibationAvalonia.Views
|
||||
@ -25,11 +26,11 @@ namespace LibationAvalonia.Views
|
||||
|
||||
//Silently download the update in the background, save it to a temp file.
|
||||
|
||||
var zipFile = System.IO.Path.GetTempFileName();
|
||||
var zipFile = Path.GetTempFileName();
|
||||
try
|
||||
{
|
||||
System.Net.Http.HttpClient cli = new();
|
||||
using var fs = System.IO.File.OpenWrite(zipFile);
|
||||
using var fs = File.OpenWrite(zipFile);
|
||||
using var dlStream = await cli.GetStreamAsync(new Uri(upgradeProperties.ZipUrl));
|
||||
await dlStream.CopyToAsync(fs);
|
||||
}
|
||||
@ -44,11 +45,11 @@ namespace LibationAvalonia.Views
|
||||
void runWindowsUpgrader(string zipFile)
|
||||
{
|
||||
var thisExe = Environment.ProcessPath;
|
||||
var thisDir = System.IO.Path.GetDirectoryName(thisExe);
|
||||
var thisDir = Path.GetDirectoryName(thisExe);
|
||||
|
||||
var zipExtractor = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "ZipExtractor.exe");
|
||||
var zipExtractor = Path.Combine(Path.GetTempPath(), "ZipExtractor.exe");
|
||||
|
||||
System.IO.File.Copy("ZipExtractor.exe", zipExtractor, overwrite: true);
|
||||
File.Copy("ZipExtractor.exe", zipExtractor, overwrite: true);
|
||||
|
||||
var psi = new System.Diagnostics.ProcessStartInfo()
|
||||
{
|
||||
@ -69,7 +70,6 @@ namespace LibationAvalonia.Views
|
||||
};
|
||||
|
||||
System.Diagnostics.Process.Start(psi);
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
try
|
||||
@ -77,34 +77,32 @@ namespace LibationAvalonia.Views
|
||||
var upgradeProperties = await Task.Run(LibationScaffolding.GetLatestRelease);
|
||||
if (upgradeProperties is null) return;
|
||||
|
||||
if (Configuration.IsWindows)
|
||||
{
|
||||
string zipFile = await downloadUpdate(upgradeProperties);
|
||||
|
||||
if (string.IsNullOrEmpty(zipFile) || !System.IO.File.Exists(zipFile))
|
||||
return;
|
||||
|
||||
var result = await MessageBox.Show(this, $"{upgradeProperties.HtmlUrl}\r\n\r\nWould you like to upgrade now?", "New version available", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
|
||||
|
||||
if (result == DialogResult.Yes)
|
||||
runWindowsUpgrader(zipFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
//We're not going to have a solution for in-place upgrade on
|
||||
//linux/mac, so just notify that an update is available.
|
||||
|
||||
const string ignoreUpdate = "IgnoreUpdate";
|
||||
var config = Configuration.Instance;
|
||||
|
||||
if (config.GetString(ignoreUpdate) == upgradeProperties.LatestRelease.ToString())
|
||||
return;
|
||||
|
||||
var notificationResult = await new UpgradeNotification(upgradeProperties).ShowDialog<DialogResult>(this);
|
||||
var notificationResult = await new UpgradeNotificationDialog(upgradeProperties, Configuration.IsWindows).ShowDialog<DialogResult>(this);
|
||||
|
||||
if (notificationResult == DialogResult.Ignore)
|
||||
config.SetString(upgradeProperties.LatestRelease.ToString(), ignoreUpdate);
|
||||
}
|
||||
|
||||
if (notificationResult != DialogResult.OK || !Configuration.IsWindows) return;
|
||||
|
||||
//Download the update file in the background,
|
||||
//then wire up installaion on window close.
|
||||
|
||||
string zipFile = await downloadUpdate(upgradeProperties);
|
||||
|
||||
if (string.IsNullOrEmpty(zipFile) || !File.Exists(zipFile))
|
||||
return;
|
||||
|
||||
Closed += (_, _) =>
|
||||
{
|
||||
if (File.Exists(zipFile))
|
||||
runWindowsUpgrader(zipFile);
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
221
Source/LibationWinForms/Dialogs/UpgradeNotificationDialog.Designer.cs
generated
Normal file
221
Source/LibationWinForms/Dialogs/UpgradeNotificationDialog.Designer.cs
generated
Normal file
@ -0,0 +1,221 @@
|
||||
namespace LibationWinForms.Dialogs
|
||||
{
|
||||
partial class UpgradeNotificationDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.Windows.Forms.Label label1;
|
||||
System.Windows.Forms.Label label2;
|
||||
System.Windows.Forms.GroupBox groupBox1;
|
||||
System.Windows.Forms.LinkLabel linkLabel3;
|
||||
System.Windows.Forms.LinkLabel linkLabel2;
|
||||
System.Windows.Forms.Label label3;
|
||||
this.packageDlLink = new System.Windows.Forms.LinkLabel();
|
||||
this.releaseNotesTbox = new System.Windows.Forms.TextBox();
|
||||
this.dontRemindBtn = new System.Windows.Forms.Button();
|
||||
this.yesBtn = new System.Windows.Forms.Button();
|
||||
this.noBtn = new System.Windows.Forms.Button();
|
||||
label1 = new System.Windows.Forms.Label();
|
||||
label2 = new System.Windows.Forms.Label();
|
||||
groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
linkLabel3 = new System.Windows.Forms.LinkLabel();
|
||||
linkLabel2 = new System.Windows.Forms.LinkLabel();
|
||||
label3 = new System.Windows.Forms.Label();
|
||||
groupBox1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.AutoSize = true;
|
||||
label1.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
||||
label1.Location = new System.Drawing.Point(12, 9);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new System.Drawing.Size(416, 21);
|
||||
label1.TabIndex = 0;
|
||||
label1.Text = "There is a new version available. Would you like to update?";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
label2.AutoSize = true;
|
||||
label2.Location = new System.Drawing.Point(12, 39);
|
||||
label2.Name = "label2";
|
||||
label2.Padding = new System.Windows.Forms.Padding(0, 0, 0, 10);
|
||||
label2.Size = new System.Drawing.Size(327, 25);
|
||||
label2.TabIndex = 1;
|
||||
label2.Text = "After you close Libation, the upgrade will start automatically.";
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
groupBox1.Controls.Add(linkLabel3);
|
||||
groupBox1.Controls.Add(linkLabel2);
|
||||
groupBox1.Controls.Add(this.packageDlLink);
|
||||
groupBox1.Controls.Add(label3);
|
||||
groupBox1.Controls.Add(this.releaseNotesTbox);
|
||||
groupBox1.Location = new System.Drawing.Point(12, 67);
|
||||
groupBox1.Name = "groupBox1";
|
||||
groupBox1.Size = new System.Drawing.Size(531, 303);
|
||||
groupBox1.TabIndex = 3;
|
||||
groupBox1.TabStop = false;
|
||||
groupBox1.Text = "Release Information";
|
||||
//
|
||||
// linkLabel3
|
||||
//
|
||||
linkLabel3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
linkLabel3.AutoSize = true;
|
||||
linkLabel3.Location = new System.Drawing.Point(348, 250);
|
||||
linkLabel3.Name = "linkLabel3";
|
||||
linkLabel3.Padding = new System.Windows.Forms.Padding(0, 0, 0, 10);
|
||||
linkLabel3.Size = new System.Drawing.Size(177, 25);
|
||||
linkLabel3.TabIndex = 1;
|
||||
linkLabel3.TabStop = true;
|
||||
linkLabel3.Text = "View the source code on GitHub";
|
||||
linkLabel3.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.GoToGithub_LinkClicked);
|
||||
//
|
||||
// linkLabel2
|
||||
//
|
||||
linkLabel2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
linkLabel2.AutoSize = true;
|
||||
linkLabel2.Location = new System.Drawing.Point(392, 275);
|
||||
linkLabel2.Name = "linkLabel2";
|
||||
linkLabel2.Padding = new System.Windows.Forms.Padding(0, 0, 0, 10);
|
||||
linkLabel2.Size = new System.Drawing.Size(133, 25);
|
||||
linkLabel2.TabIndex = 2;
|
||||
linkLabel2.TabStop = true;
|
||||
linkLabel2.Text = "Go to Libation\'s website";
|
||||
linkLabel2.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.GoToWebsite_LinkClicked);
|
||||
//
|
||||
// packageDlLink
|
||||
//
|
||||
this.packageDlLink.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.packageDlLink.AutoSize = true;
|
||||
this.packageDlLink.Location = new System.Drawing.Point(6, 275);
|
||||
this.packageDlLink.Name = "packageDlLink";
|
||||
this.packageDlLink.Padding = new System.Windows.Forms.Padding(0, 0, 0, 10);
|
||||
this.packageDlLink.Size = new System.Drawing.Size(157, 25);
|
||||
this.packageDlLink.TabIndex = 3;
|
||||
this.packageDlLink.TabStop = true;
|
||||
this.packageDlLink.Text = "[Release Package File Name]";
|
||||
this.packageDlLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.PackageDlLink_LinkClicked);
|
||||
//
|
||||
// label3
|
||||
//
|
||||
label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
label3.AutoSize = true;
|
||||
label3.Location = new System.Drawing.Point(6, 250);
|
||||
label3.Name = "label3";
|
||||
label3.Size = new System.Drawing.Size(106, 15);
|
||||
label3.TabIndex = 3;
|
||||
label3.Text = "Download Release:";
|
||||
//
|
||||
// releaseNotesTbox
|
||||
//
|
||||
this.releaseNotesTbox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.releaseNotesTbox.Location = new System.Drawing.Point(6, 22);
|
||||
this.releaseNotesTbox.Multiline = true;
|
||||
this.releaseNotesTbox.Name = "releaseNotesTbox";
|
||||
this.releaseNotesTbox.ReadOnly = true;
|
||||
this.releaseNotesTbox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
|
||||
this.releaseNotesTbox.Size = new System.Drawing.Size(519, 214);
|
||||
this.releaseNotesTbox.TabIndex = 0;
|
||||
//
|
||||
// dontRemindBtn
|
||||
//
|
||||
this.dontRemindBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.dontRemindBtn.Location = new System.Drawing.Point(12, 376);
|
||||
this.dontRemindBtn.Name = "dontRemindBtn";
|
||||
this.dontRemindBtn.Size = new System.Drawing.Size(121, 38);
|
||||
this.dontRemindBtn.TabIndex = 4;
|
||||
this.dontRemindBtn.Text = "Don\'t remind me about this release";
|
||||
this.dontRemindBtn.UseVisualStyleBackColor = true;
|
||||
this.dontRemindBtn.Click += new System.EventHandler(this.DontRemindBtn_Click);
|
||||
//
|
||||
// yesBtn
|
||||
//
|
||||
this.yesBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.yesBtn.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
||||
this.yesBtn.Location = new System.Drawing.Point(440, 376);
|
||||
this.yesBtn.Name = "yesBtn";
|
||||
this.yesBtn.Size = new System.Drawing.Size(103, 38);
|
||||
this.yesBtn.TabIndex = 6;
|
||||
this.yesBtn.Text = "Yes";
|
||||
this.yesBtn.UseVisualStyleBackColor = true;
|
||||
this.yesBtn.Click += new System.EventHandler(this.YesBtn_Click);
|
||||
//
|
||||
// noBtn
|
||||
//
|
||||
this.noBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.noBtn.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
||||
this.noBtn.Location = new System.Drawing.Point(360, 376);
|
||||
this.noBtn.Name = "noBtn";
|
||||
this.noBtn.Size = new System.Drawing.Size(74, 38);
|
||||
this.noBtn.TabIndex = 5;
|
||||
this.noBtn.Text = "No";
|
||||
this.noBtn.UseVisualStyleBackColor = true;
|
||||
this.noBtn.Click += new System.EventHandler(this.NoBtn_Click);
|
||||
//
|
||||
// UpgradeNotificationDialog
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(555, 426);
|
||||
this.Controls.Add(this.noBtn);
|
||||
this.Controls.Add(this.yesBtn);
|
||||
this.Controls.Add(this.dontRemindBtn);
|
||||
this.Controls.Add(groupBox1);
|
||||
this.Controls.Add(label2);
|
||||
this.Controls.Add(label1);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(460, 420);
|
||||
this.Name = "UpgradeNotificationDialog";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "UpgradeNotificationDialog";
|
||||
groupBox1.ResumeLayout(false);
|
||||
groupBox1.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.TextBox releaseNotesTbox;
|
||||
private System.Windows.Forms.GroupBox groupBox1;
|
||||
private System.Windows.Forms.LinkLabel linkLabel3;
|
||||
private System.Windows.Forms.LinkLabel linkLabel2;
|
||||
private System.Windows.Forms.LinkLabel packageDlLink;
|
||||
private System.Windows.Forms.Button dontRemindBtn;
|
||||
private System.Windows.Forms.Button yesBtn;
|
||||
private System.Windows.Forms.Button noBtn;
|
||||
}
|
||||
}
|
||||
71
Source/LibationWinForms/Dialogs/UpgradeNotificationDialog.cs
Normal file
71
Source/LibationWinForms/Dialogs/UpgradeNotificationDialog.cs
Normal file
@ -0,0 +1,71 @@
|
||||
using AppScaffolding;
|
||||
using Dinah.Core;
|
||||
using LibationFileManager;
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace LibationWinForms.Dialogs
|
||||
{
|
||||
public partial class UpgradeNotificationDialog : Form
|
||||
{
|
||||
private string PackageUrl { get; }
|
||||
|
||||
public UpgradeNotificationDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.SetLibationIcon();
|
||||
}
|
||||
|
||||
public UpgradeNotificationDialog(UpgradeProperties upgradeProperties) : this()
|
||||
{
|
||||
Text = $"Libation version {upgradeProperties.LatestRelease.ToString(3)} is now available.";
|
||||
PackageUrl = upgradeProperties.ZipUrl;
|
||||
packageDlLink.Text = upgradeProperties.ZipName;
|
||||
releaseNotesTbox.Text = upgradeProperties.Notes;
|
||||
|
||||
Shown += (_, _) => yesBtn.Focus();
|
||||
Load += UpgradeNotificationDialog_Load;
|
||||
}
|
||||
|
||||
private void UpgradeNotificationDialog_Load(object sender, EventArgs e)
|
||||
{
|
||||
//This dialog starts before Form1, soposition it at the center of where Form1 will be.
|
||||
var savedState = Configuration.Instance.GetNonString<FormSizeAndPosition>(nameof(Form1));
|
||||
|
||||
if (savedState is null) return;
|
||||
|
||||
int x = savedState.X + (savedState.Width - Width) / 2;
|
||||
int y = savedState.Y + (savedState.Height - Height) / 2;
|
||||
|
||||
Location = new(x, y);
|
||||
TopMost = true;
|
||||
}
|
||||
|
||||
private void PackageDlLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
=> Go.To.Url(PackageUrl);
|
||||
|
||||
private void GoToGithub_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
=> Go.To.Url(LibationScaffolding.RepositoryUrl);
|
||||
|
||||
private void GoToWebsite_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
=> Go.To.Url(LibationScaffolding.WebsiteUrl);
|
||||
|
||||
private void YesBtn_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Yes;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void DontRemindBtn_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Ignore;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void NoBtn_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.No;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="label1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="label2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="groupBox1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="linkLabel3.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="linkLabel2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="label3.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@ -89,8 +89,8 @@ namespace LibationWinForms
|
||||
|
||||
config.SetNonString(saveState, form.Name);
|
||||
}
|
||||
|
||||
private record FormSizeAndPosition
|
||||
}
|
||||
record FormSizeAndPosition
|
||||
{
|
||||
public int X;
|
||||
public int Y;
|
||||
@ -98,5 +98,4 @@ namespace LibationWinForms
|
||||
public int Width;
|
||||
public bool IsMaximized;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,7 +188,7 @@ namespace LibationWinForms
|
||||
return;
|
||||
}
|
||||
|
||||
Updater.Run(upgradeProperties.LatestRelease, upgradeProperties.ZipUrl);
|
||||
Updater.Run(upgradeProperties);
|
||||
}
|
||||
|
||||
private static void postLoggingGlobalExceptionHandling()
|
||||
|
||||
@ -1,41 +1,44 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using AppScaffolding;
|
||||
using AutoUpdaterDotNET;
|
||||
using LibationFileManager;
|
||||
using LibationWinForms.Dialogs;
|
||||
|
||||
namespace LibationWinForms
|
||||
{
|
||||
public static class Updater
|
||||
{
|
||||
private const string REPO_URL = "https://github.com/rmcrackan/Libation/releases/latest";
|
||||
|
||||
public static void Run(Version latestVersionOnServer, string downloadZipUrl)
|
||||
=> Run(latestVersionOnServer.ToString(), downloadZipUrl);
|
||||
public static void Run(string latestVersionOnServer, string downloadZipUrl)
|
||||
public static void Run(UpgradeProperties upgradeProperties)
|
||||
{
|
||||
string latestVersionOnServer = upgradeProperties.LatestRelease.ToString();
|
||||
string downloadZipUrl = upgradeProperties.ZipUrl;
|
||||
AutoUpdater.ParseUpdateInfoEvent +=
|
||||
args => args.UpdateInfo = new()
|
||||
{
|
||||
CurrentVersion = latestVersionOnServer,
|
||||
DownloadURL = downloadZipUrl,
|
||||
ChangelogURL = REPO_URL
|
||||
ChangelogURL = LibationScaffolding.RepositoryLatestUrl
|
||||
};
|
||||
AutoUpdater.CheckForUpdateEvent += AutoUpdaterOnCheckForUpdateEvent;
|
||||
AutoUpdater.Start(REPO_URL);
|
||||
}
|
||||
|
||||
private static void AutoUpdaterOnCheckForUpdateEvent(UpdateInfoEventArgs args)
|
||||
void AutoUpdaterOnCheckForUpdateEvent(UpdateInfoEventArgs args)
|
||||
{
|
||||
if (args is null || !args.IsUpdateAvailable)
|
||||
return;
|
||||
|
||||
var dialogResult = MessageBox.Show(string.Format(
|
||||
$"There is a new version available. Would you like to update?\r\n\r\nAfter you close Libation, the upgrade will start automatically."),
|
||||
"Update Available",
|
||||
MessageBoxButtons.YesNo,
|
||||
MessageBoxIcon.Information);
|
||||
if (dialogResult != DialogResult.Yes)
|
||||
const string ignoreUpdate = "IgnoreUpdate";
|
||||
var config = Configuration.Instance;
|
||||
|
||||
if (config.GetString(ignoreUpdate) == args.CurrentVersion)
|
||||
return;
|
||||
|
||||
var notificationResult = new UpgradeNotificationDialog(upgradeProperties).ShowDialog();
|
||||
|
||||
if (notificationResult == DialogResult.Ignore)
|
||||
config.SetString(upgradeProperties.LatestRelease.ToString(), ignoreUpdate);
|
||||
|
||||
if (notificationResult != DialogResult.Yes) return;
|
||||
|
||||
try
|
||||
{
|
||||
Serilog.Log.Logger.Information("Start upgrade. {@DebugInfo}", new { CurrentlyInstalled = args.InstalledVersion, TargetVersion = args.CurrentVersion });
|
||||
@ -46,5 +49,9 @@ namespace LibationWinForms
|
||||
MessageBoxLib.ShowAdminAlert(null, "Error downloading update", "Error downloading update", ex);
|
||||
}
|
||||
}
|
||||
|
||||
AutoUpdater.CheckForUpdateEvent += AutoUpdaterOnCheckForUpdateEvent;
|
||||
AutoUpdater.Start(LibationScaffolding.RepositoryLatestUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user