Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions widget-linux/openusage.py
Original file line number Diff line number Diff line change
Expand Up @@ -1169,13 +1169,30 @@ def short_slot(w):
return "cr" if n.startswith("Credit") else "day" if n.startswith("Daily") else n[:3].lower() if len(n) > 3 else n


def is_out(w):
"""Used up and still waiting on its reset (a reset already past means the numbers are behind, not the limit)."""
return w is not None and w["usedPct"] >= 100 and w.get("resetsAt") is not None and w["resetsAt"] > time.time() * 1000


def blocked_slot(short, long):
"""The used-up limit that frees up last (when you can work again), or None while every limit has room."""
out = [w for w in (short, long) if is_out(w)]
return max(out, key=lambda w: w["resetsAt"]) if out else None


def meter_line(u, w, display, accent, length, index, intro):
"""5h ▬▬▬▬▭▭ 72%"""
lv = level(w["usedPct"])
line = hbox(0)
name = label(span(short_slot(w), 10, C["muted"]))
name.set_size_request(16, -1)
line.pack_start(name, False, False, 0)
# Used up: no bar, just when it comes back, in the room the bar and the number take.
if is_out(w):
back = label(span(f"↻ {format_reset_short(w['resetsAt'])}", 11, C["error"], "bold"))
back.set_size_request(length + 32, -1)
line.pack_start(margins(back, left=3), False, False, 0)
return line
meter = Meter(w["usedPct"], lv or accent, f"{uid(u)}|{w['label']}|m", length, 5, 120 + 70 * index, intro, display)
line.pack_start(margins(meter, left=3, right=5), False, False, 0)
pct = label(span(f"{round(shown_pct(w, display))}%", 11, lv or C["text"], "bold"))
Expand Down Expand Up @@ -1281,6 +1298,12 @@ def strip_chip(u, display, gauge, index, intro):
sub, color = f"{slot_name(other)} {round(shown_pct(other, display))}%", level(other["usedPct"]) or C["muted"]
else:
sub, color = short_account(u), C["muted"]
# A used-up limit: the second line tells when it comes back instead.
blocked = blocked_slot(short, long)
if blocked is not None:
# Named when it isn't the limit on the line above.
name = "" if blocked is main else f"{slot_name(blocked)} "
sub, color = f"{name}↻ {format_reset_short(blocked['resetsAt'])}", C["error"]
elif extras:
col.pack_start(label(span(extras[0]["value"], 13, weight="bold")), False, False, 0)
sub, color = extras[0]["label"].lower(), C["muted"]
Expand Down
33 changes: 27 additions & 6 deletions widget-mac/OpenUsage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,11 @@ func shortSlot(_ w: UsageWindow) -> String {
return n.count > 3 ? String(n.prefix(3)).lowercased() : n
}

/** Used up and still waiting on its reset (a reset already past means the numbers are behind, not the limit). */
func isOut(_ w: UsageWindow) -> Bool {
w.usedPct >= 100 && (w.resetsAt ?? 0) > Date().timeIntervalSince1970 * 1000
}

/** 5h ▬▬▬▬▭▭ 72% */
struct MeterLine: View {
let w: UsageWindow
Expand All @@ -787,11 +792,18 @@ struct MeterLine: View {
let lv = level(w.usedPct)
HStack(spacing: 0) {
Text(shortSlot(w)).font(.system(size: 10)).foregroundColor(C.muted).frame(minWidth: 16, alignment: .leading)
Meter(used: w.usedPct, display: display, color: lv ?? accent, width: length, height: 5, delay: 0.12 + 0.07 * Double(index))
.padding(.leading, 3)
.padding(.trailing, 5)
Text("\(Int(shown(w, display).rounded()))%").font(.system(size: 11, weight: .semibold)).foregroundColor(lv ?? C.text)
.frame(minWidth: 27, alignment: .leading)
if isOut(w) {
// Used up: no bar, just when it comes back, in the room the bar and the number take.
Text("\u{21BB} \(formatResetShort(w.resetsAt))").font(.system(size: 11, weight: .semibold)).foregroundColor(C.error)
.frame(minWidth: length + 32, alignment: .leading)
.padding(.leading, 3)
} else {
Meter(used: w.usedPct, display: display, color: lv ?? accent, width: length, height: 5, delay: 0.12 + 0.07 * Double(index))
.padding(.leading, 3)
.padding(.trailing, 5)
Text("\(Int(shown(w, display).rounded()))%").font(.system(size: 11, weight: .semibold)).foregroundColor(lv ?? C.text)
.frame(minWidth: 27, alignment: .leading)
}
}
}
}
Expand Down Expand Up @@ -1157,6 +1169,11 @@ struct CompactCard: View {

// ---- strip ---------------------------------------------------------------------------

/** The used-up limit that frees up last (when you can work again), or nil while every limit has room. */
func blocked(_ s: Slots) -> UsageWindow? {
[s.short, s.long].compactMap { $0 }.filter(isOut).max { $0.resetsAt! < $1.resetsAt! }
}

/** One account in the strip: a ring pair around the mark (or the mark and a meter per limit) and its numbers. */
struct StripChip: View {
let u: ProviderUsage
Expand Down Expand Up @@ -1225,7 +1242,11 @@ struct StripChip: View {
(Text("\(Int(shown(main, display).rounded()))%").font(.system(size: 13, weight: .semibold))
.foregroundColor(level(main.usedPct) ?? C.text)
+ Text(" \(slotName(main))").font(.system(size: 10)).foregroundColor(C.muted))
if let other = other {
// A used-up limit: the second line tells when it comes back instead.
if let b = blocked(s) {
// Named when it isn't the limit on the line above.
Text("\(b.label == main.label ? "" : slotName(b) + " ")\u{21BB} \(formatResetShort(b.resetsAt))").font(.system(size: 10)).foregroundColor(C.error)
} else if let other = other {
Text("\(slotName(other)) \(Int(shown(other, display).rounded()))%").font(.system(size: 10))
.foregroundColor(level(other.usedPct) ?? C.muted)
} else if !shortAccount(u).isEmpty {
Expand Down
26 changes: 25 additions & 1 deletion widget/usage-widget.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,14 @@ function Get-Shown([double]$used) { if ($script:display -eq 'used') { $used } el
# How much of a ring to fill: the shown value, except that a used-up limit is always a full ring (in red).
function Get-ArcPct([double]$used) { if ($used -ge 100) { 100 } else { Get-Shown $used } }

# Used up and still waiting on its reset (a reset already past means the numbers are behind, not the limit).
function Test-Out($w) { $w -and $w.usedPct -ge 100 -and $w.resetsAt -and [double]$w.resetsAt -gt [DateTimeOffset]::Now.ToUnixTimeMilliseconds() }

# The used-up limit that frees up last (when you can work again), or nothing while every limit has room.
function Get-Blocked($slots) {
@($slots.short, $slots.long) | Where-Object { Test-Out $_ } | Sort-Object { [double]$_.resetsAt } | Select-Object -Last 1
}

function Get-SlotName($w) {
if (-not $w) { return '' }
switch -Regex ($w.label) { 'Hour' { '5h' } 'Week|7-Day' { 'wk' } 'Month|Billing' { 'mo' } default { $w.label } }
Expand Down Expand Up @@ -849,6 +857,15 @@ function New-Meter($w, [string]$accent, [int]$index, [double]$len = 46) {
$name.MinWidth = 16
$name.VerticalAlignment = 'Center'
$row.Children.Add($name) | Out-Null
# Used up: no bar, just when it comes back, in the room the bar and the number take.
if (Test-Out $w) {
$back = New-Text "$([char]0x21BB) $(Format-ResetShort $w.resetsAt)" $C.Error 11 'SemiBold'
$back.MinWidth = $len + 32
$back.Margin = '3,0,0,0'
$back.VerticalAlignment = 'Center'
$row.Children.Add($back) | Out-Null
return $row
}
$track = New-Fill $used $color $index 5
$track.Width = $len
$track.VerticalAlignment = 'Center'
Expand Down Expand Up @@ -942,8 +959,15 @@ function New-BarChip($u, [int]$index) {
$text.Children.Add((New-Text ([string]($u.name -replace ' \(.*\)$', '')) $C.Text 12 'SemiBold')) | Out-Null
$sub = 'no data'
}
$lv = if ($other) { Level $other.usedPct } else { $null }
# A used-up limit: the second line tells when it comes back instead.
$blocked = Get-Blocked $slots
if ($blocked) {
# Named when it isn't the limit on the line above.
$sub = "$(if ($blocked -ne $main) { (Get-SlotName $blocked) + ' ' })$([char]0x21BB) $(Format-ResetShort $blocked.resetsAt)"
$lv = $C.Error
}
if ($sub) {
$lv = if ($other) { Level $other.usedPct } else { $null }
$s2 = New-Text $sub $(if ($lv) { $lv } else { $C.Muted }) 10
$s2.Margin = '0,-1,0,0'
$text.Children.Add($s2) | Out-Null
Expand Down
Loading