feat(desktop): add licence processing

This commit is contained in:
Anna 2020-11-11 21:25:59 -05:00
parent 033d4add13
commit 0416c9efaa
6 changed files with 179 additions and 4 deletions

View File

@ -31,7 +31,7 @@ namespace XIVChat_Desktop {
public event PropertyChangedEventHandler? PropertyChanged;
private void Application_Startup(object sender, StartupEventArgs e) {
private async void Application_Startup(object sender, StartupEventArgs e) {
try {
this.Config = Configuration.Load() ?? new Configuration();
} catch (Exception ex) {
@ -62,12 +62,24 @@ namespace XIVChat_Desktop {
)
);
var wnd = new MainWindow();
this.Window = wnd;
// I guess this gets initialised where you call it the first time, so initialise it on the UI thread
this.Dispatcher.Invoke(() => { });
#if RELEASE
if (string.IsNullOrWhiteSpace(this.Config.LicenceKey) || !(await LicenceWindow.LicenceInfo(this.Config.LicenceKey)).Valid()) {
var lic = new LicenceWindow(null, true);
lic.Show();
return;
}
#endif
this.InitialiseWindow();
}
public void InitialiseWindow() {
var wnd = new MainWindow();
this.Window = wnd;
wnd.Show();
// initialise a config window to apply all our settings

View File

@ -16,6 +16,8 @@ namespace XIVChat_Desktop {
public class Configuration : INotifyPropertyChanged {
public event PropertyChangedEventHandler? PropertyChanged;
public string? LicenceKey { get; set; }
public KeyPair KeyPair { get; set; } = PublicKeyBox.GenerateKeyPair();
public ObservableCollection<SavedServer> Servers { get; set; } = new ObservableCollection<SavedServer>();

View File

@ -0,0 +1,32 @@
<Window x:Class="XIVChat_Desktop.LicenceWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:XIVChat_Desktop"
xmlns:ui="http://schemas.modernwpf.com/2019"
ui:WindowHelper.UseModernWindowStyle="True"
mc:Ignorable="d"
Title="Licence"
WindowStartupLocation="CenterOwner"
ContentRendered="LicenceWindow_OnContentRendered"
SizeToContent="WidthAndHeight"
d:DataContext="{d:DesignInstance local:LicenceWindow}">
<StackPanel Margin="8">
<ProgressBar x:Name="Loading"
IsIndeterminate="True" />
<StackPanel x:Name="LicenceInfoPanel"
Visibility="Collapsed">
<TextBlock x:Name="LicenceDescription"
Text="Checking licence..." />
<TextBox x:Name="LicenceKey"
Text="{Binding App.Config.LicenceKey}"
ui:ControlHelper.Header="Licence key" />
<Button x:Name="CheckButton"
Margin="0,8,0,0"
Content="Check"
Click="Check_Click"
IsEnabled="False" />
</StackPanel>
</StackPanel>
</Window>

View File

@ -0,0 +1,123 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows;
using Windows.Web.Http;
using Newtonsoft.Json;
namespace XIVChat_Desktop {
public partial class LicenceWindow {
public App App => (App)Application.Current;
private readonly bool startAfterSuccess;
public LicenceWindow(Window? owner, bool startAfterSuccess) {
this.Owner = owner;
this.startAfterSuccess = startAfterSuccess;
this.InitializeComponent();
this.DataContext = this;
var empty = string.IsNullOrWhiteSpace(this.App.Config.LicenceKey);
if (empty) {
this.CheckButton.IsEnabled = true;
this.LicenceDescription.Text = "No licence key has been supplied. Please enter one.";
this.SetLoading(false);
return;
}
_ = Task.Run(async () => {
await this.Check();
this.Dispatch(() => this.SetLoading(false));
});
}
private void SetLoading(bool loading) {
this.Loading.Visibility = loading ? Visibility.Visible : Visibility.Collapsed;
this.LicenceInfoPanel.Visibility = loading ? Visibility.Collapsed : Visibility.Visible;
}
private async Task<bool> Check(bool increment = false) {
this.Dispatch(() => this.CheckButton.IsEnabled = false);
var licence = await LicenceInfo(this.App.Config.LicenceKey!, increment);
var valid = licence.Valid();
this.Dispatch(() => {
this.CheckButton.IsEnabled = true;
this.LicenceDescription.Text = valid
? $"Valid licence key for {licence.purchase.email}. Thank you!"
: "Invalid licence key. Please check the key and try again.";
});
return valid;
}
private async void Check_Click(object sender, RoutedEventArgs e) {
this.App.Config.Save();
var valid = await this.Check(true);
if (!valid || !this.startAfterSuccess) {
return;
}
this.App.InitialiseWindow();
this.Close();
}
public static async Task<LicenceResponse> LicenceInfo(string key, bool increment = false) {
var uri = new Uri("https://api.gumroad.com/v2/licenses/verify");
var data = new Dictionary<string, string> {
["product_permalink"] = "kvQIw",
["license_key"] = key,
["increment_uses_count"] = increment ? "true" : "false",
};
var client = new HttpClient();
var res = await client.PostAsync(uri, new HttpFormUrlEncodedContent(data));
var response = JsonConvert.DeserializeObject<LicenceResponse>(await res.Content.ReadAsStringAsync());
return response;
}
private void LicenceWindow_OnContentRendered(object? sender, EventArgs e) {
this.InvalidateVisual();
}
}
public class LicenceResponse {
public readonly bool success;
public readonly uint uses;
public readonly Purchase purchase;
public LicenceResponse(bool success, uint uses, Purchase purchase) {
this.success = success;
this.uses = uses;
this.purchase = purchase;
}
public bool Valid() {
return this.success && !this.purchase.refunded && !this.purchase.chargebacked;
}
}
public class Purchase {
public readonly string id;
public readonly string productName;
public readonly DateTime createdAt;
public readonly string fullName;
public readonly bool refunded;
public readonly bool chargebacked;
public readonly string email;
public Purchase(string id, string productName, DateTime createdAt, string fullName, bool refunded, bool chargebacked, string email) {
this.id = id;
this.productName = productName;
this.createdAt = createdAt;
this.fullName = fullName;
this.refunded = refunded;
this.chargebacked = chargebacked;
this.email = email;
}
}
}

View File

@ -34,6 +34,8 @@
<MenuItem Header="Export"
Click="Export_Click" />
<Separator />
<MenuItem Header="Licence"
Click="Licence_Click" />
<MenuItem Header="Configuration"
Click="Configuration_Click" />
</MenuItem>

View File

@ -185,5 +185,9 @@ namespace XIVChat_Desktop {
private void Export_Click(object sender, RoutedEventArgs e) {
new Export(this).Show();
}
private void Licence_Click(object sender, RoutedEventArgs e) {
new LicenceWindow(this, false).Show();
}
}
}