TASK 10: Polar billing + Velopack auto-updates (steps 1-7)
This commit is contained in:
@@ -1027,6 +1027,76 @@ public class LayoutStore : IDisposable
|
||||
return (string)cmd.ExecuteScalar()!;
|
||||
}
|
||||
|
||||
// ─── License (TASK 10 — Polar billing) ───
|
||||
|
||||
/// <summary>The saved license key, or null if never entered.</summary>
|
||||
public string? LoadLicenseKey()
|
||||
{
|
||||
using var cmd = _connection.CreateCommand();
|
||||
cmd.CommandText = "SELECT Value FROM Settings WHERE Key = 'LicenseKey';";
|
||||
var value = cmd.ExecuteScalar() as string;
|
||||
return string.IsNullOrWhiteSpace(value) ? null : value;
|
||||
}
|
||||
|
||||
public void SaveLicenseKey(string? key)
|
||||
{
|
||||
using var cmd = _connection.CreateCommand();
|
||||
cmd.CommandText = "DELETE FROM Settings WHERE Key = 'LicenseKey';";
|
||||
cmd.ExecuteNonQuery();
|
||||
if (string.IsNullOrWhiteSpace(key)) return;
|
||||
|
||||
using var insert = _connection.CreateCommand();
|
||||
insert.CommandText = "INSERT INTO Settings (Key, Value) VALUES ('LicenseKey', $value);";
|
||||
insert.Parameters.AddWithValue("$value", key);
|
||||
insert.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
/// <summary>When the license was last validated online (ISO 8601), or null if never.</summary>
|
||||
public DateTime? LoadLicenseValidatedAt()
|
||||
{
|
||||
using var cmd = _connection.CreateCommand();
|
||||
cmd.CommandText = "SELECT Value FROM Settings WHERE Key = 'LicenseValidatedAt';";
|
||||
var value = cmd.ExecuteScalar() as string;
|
||||
if (string.IsNullOrWhiteSpace(value)) return null;
|
||||
return DateTime.TryParse(value, out var dt) ? dt : null;
|
||||
}
|
||||
|
||||
public void SaveLicenseValidatedAt(DateTime? dt)
|
||||
{
|
||||
using var cmd = _connection.CreateCommand();
|
||||
cmd.CommandText = "DELETE FROM Settings WHERE Key = 'LicenseValidatedAt';";
|
||||
cmd.ExecuteNonQuery();
|
||||
if (dt == null) return;
|
||||
|
||||
using var insert = _connection.CreateCommand();
|
||||
insert.CommandText = "INSERT INTO Settings (Key, Value) VALUES ('LicenseValidatedAt', $value);";
|
||||
insert.Parameters.AddWithValue("$value", dt.Value.ToString("o"));
|
||||
insert.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
/// <summary>Cached premium state (1 = premium, 0 = free). Used for offline
|
||||
/// grace period — the app checks online at startup but uses this cached
|
||||
/// value when offline.</summary>
|
||||
public bool LoadIsPremium()
|
||||
{
|
||||
using var cmd = _connection.CreateCommand();
|
||||
cmd.CommandText = "SELECT Value FROM Settings WHERE Key = 'IsPremium';";
|
||||
var value = cmd.ExecuteScalar() as string;
|
||||
return value == "1";
|
||||
}
|
||||
|
||||
public void SaveIsPremium(bool isPremium)
|
||||
{
|
||||
using var cmd = _connection.CreateCommand();
|
||||
cmd.CommandText = "DELETE FROM Settings WHERE Key = 'IsPremium';";
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
using var insert = _connection.CreateCommand();
|
||||
insert.CommandText = "INSERT INTO Settings (Key, Value) VALUES ('IsPremium', $value);";
|
||||
insert.Parameters.AddWithValue("$value", isPremium ? "1" : "0");
|
||||
insert.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_connection.Dispose();
|
||||
|
||||
Reference in New Issue
Block a user