289 lines
7.7 KiB
C#
289 lines
7.7 KiB
C#
using IronLicensing.Client;
|
|
using IronLicensing.Client.Models;
|
|
|
|
namespace IronServices.Maui.Controls;
|
|
|
|
/// <summary>
|
|
/// A reusable license activation view for IronLicensing.
|
|
/// </summary>
|
|
public partial class LicenseActivationView : ContentView
|
|
{
|
|
private ILicenseManager? _licenseManager;
|
|
|
|
public LicenseActivationView()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
#region Bindable Properties
|
|
|
|
/// <summary>
|
|
/// The ILicenseManager to use for license validation.
|
|
/// </summary>
|
|
public static readonly BindableProperty LicenseManagerProperty = BindableProperty.Create(
|
|
nameof(LicenseManager),
|
|
typeof(ILicenseManager),
|
|
typeof(LicenseActivationView),
|
|
null,
|
|
propertyChanged: (b, o, n) => ((LicenseActivationView)b)._licenseManager = n as ILicenseManager);
|
|
|
|
public ILicenseManager? LicenseManager
|
|
{
|
|
get => (ILicenseManager?)GetValue(LicenseManagerProperty);
|
|
set => SetValue(LicenseManagerProperty, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// The title text.
|
|
/// </summary>
|
|
public static readonly BindableProperty TitleProperty = BindableProperty.Create(
|
|
nameof(Title),
|
|
typeof(string),
|
|
typeof(LicenseActivationView),
|
|
"Activate License",
|
|
propertyChanged: (b, o, n) => ((LicenseActivationView)b).TitleLabel.Text = n as string);
|
|
|
|
public string Title
|
|
{
|
|
get => (string)GetValue(TitleProperty);
|
|
set => SetValue(TitleProperty, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// The subtitle text.
|
|
/// </summary>
|
|
public static readonly BindableProperty SubtitleProperty = BindableProperty.Create(
|
|
nameof(Subtitle),
|
|
typeof(string),
|
|
typeof(LicenseActivationView),
|
|
"Enter your license key to activate",
|
|
propertyChanged: (b, o, n) => ((LicenseActivationView)b).SubtitleLabel.Text = n as string);
|
|
|
|
public string Subtitle
|
|
{
|
|
get => (string)GetValue(SubtitleProperty);
|
|
set => SetValue(SubtitleProperty, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Pre-filled license key.
|
|
/// </summary>
|
|
public static readonly BindableProperty LicenseKeyProperty = BindableProperty.Create(
|
|
nameof(LicenseKey),
|
|
typeof(string),
|
|
typeof(LicenseActivationView),
|
|
null,
|
|
BindingMode.TwoWay,
|
|
propertyChanged: (b, o, n) => ((LicenseActivationView)b).LicenseKeyEntry.Text = n as string);
|
|
|
|
public string? LicenseKey
|
|
{
|
|
get => (string?)GetValue(LicenseKeyProperty);
|
|
set => SetValue(LicenseKeyProperty, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Whether to show the help link.
|
|
/// </summary>
|
|
public static readonly BindableProperty ShowHelpLinkProperty = BindableProperty.Create(
|
|
nameof(ShowHelpLink),
|
|
typeof(bool),
|
|
typeof(LicenseActivationView),
|
|
true,
|
|
propertyChanged: (b, o, n) => ((LicenseActivationView)b).HelpLink.IsVisible = (bool)n);
|
|
|
|
public bool ShowHelpLink
|
|
{
|
|
get => (bool)GetValue(ShowHelpLinkProperty);
|
|
set => SetValue(ShowHelpLinkProperty, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// URL to open when help link is tapped.
|
|
/// </summary>
|
|
public static readonly BindableProperty HelpUrlProperty = BindableProperty.Create(
|
|
nameof(HelpUrl),
|
|
typeof(string),
|
|
typeof(LicenseActivationView),
|
|
"https://ironservices.io/docs/licensing");
|
|
|
|
public string HelpUrl
|
|
{
|
|
get => (string)GetValue(HelpUrlProperty);
|
|
set => SetValue(HelpUrlProperty, value);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Events
|
|
|
|
/// <summary>
|
|
/// Raised when license activation is successful.
|
|
/// </summary>
|
|
public event EventHandler<LicenseActivatedEventArgs>? LicenseActivated;
|
|
|
|
/// <summary>
|
|
/// Raised when license activation fails.
|
|
/// </summary>
|
|
public event EventHandler<LicenseActivationFailedEventArgs>? ActivationFailed;
|
|
|
|
/// <summary>
|
|
/// Raised when help link is tapped.
|
|
/// </summary>
|
|
public event EventHandler? HelpRequested;
|
|
|
|
#endregion
|
|
|
|
#region Event Handlers
|
|
|
|
private async void OnActivateClicked(object sender, EventArgs e)
|
|
{
|
|
if (_licenseManager == null)
|
|
{
|
|
ShowError("License manager not configured");
|
|
return;
|
|
}
|
|
|
|
var licenseKey = LicenseKeyEntry.Text?.Trim();
|
|
|
|
if (string.IsNullOrEmpty(licenseKey))
|
|
{
|
|
ShowError("Please enter a license key");
|
|
return;
|
|
}
|
|
|
|
SetLoading(true);
|
|
HideError();
|
|
HideStatus();
|
|
|
|
try
|
|
{
|
|
var result = await _licenseManager.ActivateAsync(licenseKey);
|
|
|
|
if (result.Success)
|
|
{
|
|
ShowStatus(true, "License activated successfully!");
|
|
LicenseActivated?.Invoke(this, new LicenseActivatedEventArgs(result));
|
|
}
|
|
else
|
|
{
|
|
ShowError(result.ErrorMessage ?? "Invalid license key");
|
|
ActivationFailed?.Invoke(this, new LicenseActivationFailedEventArgs(result.ErrorMessage ?? "Invalid license key"));
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ShowError($"Error: {ex.Message}");
|
|
ActivationFailed?.Invoke(this, new LicenseActivationFailedEventArgs(ex.Message));
|
|
}
|
|
finally
|
|
{
|
|
SetLoading(false);
|
|
}
|
|
}
|
|
|
|
private async void OnHelpTapped(object sender, EventArgs e)
|
|
{
|
|
HelpRequested?.Invoke(this, EventArgs.Empty);
|
|
|
|
try
|
|
{
|
|
await Browser.OpenAsync(HelpUrl, BrowserLaunchMode.SystemPreferred);
|
|
}
|
|
catch
|
|
{
|
|
// Ignore if can't open browser
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Helper Methods
|
|
|
|
private void SetLoading(bool isLoading)
|
|
{
|
|
ActivateButton.IsEnabled = !isLoading;
|
|
ActivateButton.IsVisible = !isLoading;
|
|
LoadingIndicator.IsRunning = isLoading;
|
|
LoadingIndicator.IsVisible = isLoading;
|
|
LicenseKeyEntry.IsEnabled = !isLoading;
|
|
}
|
|
|
|
private void ShowError(string message)
|
|
{
|
|
ErrorLabel.Text = message;
|
|
ErrorLabel.IsVisible = true;
|
|
}
|
|
|
|
private void HideError()
|
|
{
|
|
ErrorLabel.IsVisible = false;
|
|
}
|
|
|
|
private void ShowStatus(bool success, string message)
|
|
{
|
|
StatusFrame.IsVisible = true;
|
|
StatusFrame.BackgroundColor = success
|
|
? Color.FromArgb("#D1FAE5") // Green background
|
|
: Color.FromArgb("#FEE2E2"); // Red background
|
|
StatusIcon.Text = success ? "✓" : "✗";
|
|
StatusIcon.TextColor = success ? Colors.Green : Colors.Red;
|
|
StatusLabel.Text = message;
|
|
StatusLabel.TextColor = success ? Colors.Green : Colors.Red;
|
|
}
|
|
|
|
private void HideStatus()
|
|
{
|
|
StatusFrame.IsVisible = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validates the current license without activating a new one.
|
|
/// </summary>
|
|
public async Task<bool> ValidateAsync()
|
|
{
|
|
if (_licenseManager == null) return false;
|
|
|
|
var licenseKey = LicenseKeyEntry.Text?.Trim();
|
|
|
|
try
|
|
{
|
|
var result = await _licenseManager.ValidateAsync(licenseKey);
|
|
return result.Success;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Event args for successful license activation.
|
|
/// </summary>
|
|
public class LicenseActivatedEventArgs : EventArgs
|
|
{
|
|
public LicenseResult Result { get; }
|
|
public LicenseInfo? License => Result.License;
|
|
|
|
public LicenseActivatedEventArgs(LicenseResult result)
|
|
{
|
|
Result = result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Event args for failed license activation.
|
|
/// </summary>
|
|
public class LicenseActivationFailedEventArgs : EventArgs
|
|
{
|
|
public string Error { get; }
|
|
|
|
public LicenseActivationFailedEventArgs(string error)
|
|
{
|
|
Error = error;
|
|
}
|
|
}
|