Add proper Upgrade form

This commit is contained in:
Michael Bucari-Tovo 2023-01-07 18:09:37 -07:00
parent ed15614288
commit e3b7cbcc2a
13 changed files with 623 additions and 175 deletions

View File

@ -29,6 +29,9 @@ namespace AppScaffolding
public static class LibationScaffolding 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 ReleaseIdentifier ReleaseIdentifier { get; private set; }
public static VarietyType Variety public static VarietyType Variety
=> ReleaseIdentifier == ReleaseIdentifier.WindowsClassic ? VarietyType.Classic => ReleaseIdentifier == ReleaseIdentifier.WindowsClassic ? VarietyType.Classic
@ -354,7 +357,7 @@ namespace AppScaffolding
public static UpgradeProperties GetLatestRelease() public static UpgradeProperties GetLatestRelease()
{ {
// timed out // 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) if (latest is null || zip is null)
return null; return null;
@ -363,9 +366,6 @@ namespace AppScaffolding
if (!Version.TryParse(latestVersionString, out var latestRelease)) if (!Version.TryParse(latestVersionString, out var latestRelease))
return null; return null;
// we're up to date
if (latestRelease <= BuildVersion)
return null;
// we have an update // we have an update
@ -378,7 +378,7 @@ namespace AppScaffolding
zipUrl 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) private static (Octokit.Release, Octokit.ReleaseAsset) getLatestRelease(TimeSpan timeout)
{ {

View File

@ -1,6 +1,34 @@
using System; using System;
using System.Text.RegularExpressions;
namespace AppScaffolding 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;
}
}
} }

View File

@ -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&#x0a;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>

View File

@ -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");
}
}

View File

@ -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&#x0a;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>

View File

@ -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);
}
}

View File

@ -2,6 +2,7 @@
using LibationAvalonia.Dialogs; using LibationAvalonia.Dialogs;
using LibationFileManager; using LibationFileManager;
using System; using System;
using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace LibationAvalonia.Views namespace LibationAvalonia.Views
@ -25,11 +26,11 @@ namespace LibationAvalonia.Views
//Silently download the update in the background, save it to a temp file. //Silently download the update in the background, save it to a temp file.
var zipFile = System.IO.Path.GetTempFileName(); var zipFile = Path.GetTempFileName();
try try
{ {
System.Net.Http.HttpClient cli = new(); 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)); using var dlStream = await cli.GetStreamAsync(new Uri(upgradeProperties.ZipUrl));
await dlStream.CopyToAsync(fs); await dlStream.CopyToAsync(fs);
} }
@ -44,11 +45,11 @@ namespace LibationAvalonia.Views
void runWindowsUpgrader(string zipFile) void runWindowsUpgrader(string zipFile)
{ {
var thisExe = Environment.ProcessPath; 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() var psi = new System.Diagnostics.ProcessStartInfo()
{ {
@ -69,7 +70,6 @@ namespace LibationAvalonia.Views
}; };
System.Diagnostics.Process.Start(psi); System.Diagnostics.Process.Start(psi);
Environment.Exit(0);
} }
try try
@ -77,34 +77,32 @@ namespace LibationAvalonia.Views
var upgradeProperties = await Task.Run(LibationScaffolding.GetLatestRelease); var upgradeProperties = await Task.Run(LibationScaffolding.GetLatestRelease);
if (upgradeProperties is null) return; 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"; const string ignoreUpdate = "IgnoreUpdate";
var config = Configuration.Instance; var config = Configuration.Instance;
if (config.GetString(ignoreUpdate) == upgradeProperties.LatestRelease.ToString()) if (config.GetString(ignoreUpdate) == upgradeProperties.LatestRelease.ToString())
return; 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) if (notificationResult == DialogResult.Ignore)
config.SetString(upgradeProperties.LatestRelease.ToString(), ignoreUpdate); 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) catch (Exception ex)
{ {

View 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;
}
}

View 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();
}
}
}

View File

@ -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>

View File

@ -89,8 +89,8 @@ namespace LibationWinForms
config.SetNonString(saveState, form.Name); config.SetNonString(saveState, form.Name);
} }
}
private record FormSizeAndPosition record FormSizeAndPosition
{ {
public int X; public int X;
public int Y; public int Y;
@ -99,4 +99,3 @@ namespace LibationWinForms
public bool IsMaximized; public bool IsMaximized;
} }
} }
}

View File

@ -188,7 +188,7 @@ namespace LibationWinForms
return; return;
} }
Updater.Run(upgradeProperties.LatestRelease, upgradeProperties.ZipUrl); Updater.Run(upgradeProperties);
} }
private static void postLoggingGlobalExceptionHandling() private static void postLoggingGlobalExceptionHandling()

View File

@ -1,41 +1,44 @@
using System; using System;
using System.Windows.Forms; using System.Windows.Forms;
using AppScaffolding;
using AutoUpdaterDotNET; using AutoUpdaterDotNET;
using LibationFileManager;
using LibationWinForms.Dialogs;
namespace LibationWinForms namespace LibationWinForms
{ {
public static class Updater public static class Updater
{ {
private const string REPO_URL = "https://github.com/rmcrackan/Libation/releases/latest"; public static void Run(UpgradeProperties upgradeProperties)
public static void Run(Version latestVersionOnServer, string downloadZipUrl)
=> Run(latestVersionOnServer.ToString(), downloadZipUrl);
public static void Run(string latestVersionOnServer, string downloadZipUrl)
{ {
string latestVersionOnServer = upgradeProperties.LatestRelease.ToString();
string downloadZipUrl = upgradeProperties.ZipUrl;
AutoUpdater.ParseUpdateInfoEvent += AutoUpdater.ParseUpdateInfoEvent +=
args => args.UpdateInfo = new() args => args.UpdateInfo = new()
{ {
CurrentVersion = latestVersionOnServer, CurrentVersion = latestVersionOnServer,
DownloadURL = downloadZipUrl, 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) if (args is null || !args.IsUpdateAvailable)
return; return;
var dialogResult = MessageBox.Show(string.Format( const string ignoreUpdate = "IgnoreUpdate";
$"There is a new version available. Would you like to update?\r\n\r\nAfter you close Libation, the upgrade will start automatically."), var config = Configuration.Instance;
"Update Available",
MessageBoxButtons.YesNo, if (config.GetString(ignoreUpdate) == args.CurrentVersion)
MessageBoxIcon.Information);
if (dialogResult != DialogResult.Yes)
return; return;
var notificationResult = new UpgradeNotificationDialog(upgradeProperties).ShowDialog();
if (notificationResult == DialogResult.Ignore)
config.SetString(upgradeProperties.LatestRelease.ToString(), ignoreUpdate);
if (notificationResult != DialogResult.Yes) return;
try try
{ {
Serilog.Log.Logger.Information("Start upgrade. {@DebugInfo}", new { CurrentlyInstalled = args.InstalledVersion, TargetVersion = args.CurrentVersion }); 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); MessageBoxLib.ShowAdminAlert(null, "Error downloading update", "Error downloading update", ex);
} }
} }
AutoUpdater.CheckForUpdateEvent += AutoUpdaterOnCheckForUpdateEvent;
AutoUpdater.Start(LibationScaffolding.RepositoryLatestUrl);
}
} }
} }