41 lines
1.6 KiB
C#
41 lines
1.6 KiB
C#
|
|
namespace ClaudeOverview.Models;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Subscription usage pulled from the Claude /api/oauth/usage endpoint.
|
|||
|
|
/// Percentages are 0–100.
|
|||
|
|
/// </summary>
|
|||
|
|
public sealed class UsageInfo
|
|||
|
|
{
|
|||
|
|
/// <summary>Length of the rolling session-limit block (the API's "five_hour" bucket).</summary>
|
|||
|
|
public static readonly TimeSpan SessionWindow = TimeSpan.FromHours(5);
|
|||
|
|
|
|||
|
|
public double SessionPercent { get; set; }
|
|||
|
|
public DateTime? SessionResetsAt { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>UTC start of the current session-limit window (its reset time minus the 5-hour block).</summary>
|
|||
|
|
public DateTime? SessionWindowStartUtc =>
|
|||
|
|
SessionResetsAt is { } r ? r.ToUniversalTime() - SessionWindow : null;
|
|||
|
|
|
|||
|
|
public double WeeklyPercent { get; set; }
|
|||
|
|
public DateTime? WeeklyResetsAt { get; set; }
|
|||
|
|
|
|||
|
|
public string? Error { get; set; }
|
|||
|
|
public bool Ok => Error is null;
|
|||
|
|
|
|||
|
|
/// <summary>True when the last fetch was rejected with HTTP 429 (rate limited).</summary>
|
|||
|
|
public bool RateLimited { get; set; }
|
|||
|
|
|
|||
|
|
/// <summary>Server-suggested wait before retrying (from the Retry-After header), if any.</summary>
|
|||
|
|
public TimeSpan? RetryAfter { get; set; }
|
|||
|
|
|
|||
|
|
public static string ResetsIn(DateTime? resetsAtUtc)
|
|||
|
|
{
|
|||
|
|
if (resetsAtUtc is null) return "";
|
|||
|
|
var span = resetsAtUtc.Value.ToUniversalTime() - DateTime.UtcNow;
|
|||
|
|
if (span <= TimeSpan.Zero) return "resetting…";
|
|||
|
|
if (span < TimeSpan.FromHours(1)) return $"resets in {(int)span.TotalMinutes}m";
|
|||
|
|
if (span < TimeSpan.FromDays(1)) return $"resets in {(int)span.TotalHours}h{span.Minutes:00}m";
|
|||
|
|
return $"resets in {(int)span.TotalDays}d{span.Hours}h";
|
|||
|
|
}
|
|||
|
|
}
|