Skip to content

Feature request: opt-in compact menubar width for short cost strings #129

@calvindotsg

Description

@calvindotsg

Summary

Would you consider an opt-in compact mode for the menubar that renders the cost without the decimals and a tighter fixed slot? Something like 🔥$110 instead of 🔥 $110.20, with the reserved width shrunk to match. Default off; existing users would see no change.

Image

(CodeBurnMenubar.app v0.8.7 on macOS 15.4, highlighted; neighbouring items visible for width comparison.)

Acknowledging the current design

The 130 pt slot is clearly intentional. From mac/Sources/CodeBurnMenubar/CodeBurnApp.swift:

/// Fixed so the popover's anchor point doesn't shift each time today's cost changes.
private let statusItemFixedWidth: CGFloat = 130
// Fixed width so the popover anchor (and thus popover position) doesn't shift
// every time today's cost or findings badge changes.
statusItem = NSStatusBar.system.statusItem(withLength: statusItemFixedWidth)

Anchor stability across the 15s refresh cycle is a good default and this proposal keeps it: just a narrower fixed width when compact is on.

Observation

For typical daily costs in major currencies (one to four digits, with or without a symbol), 130 pt reserves more horizontal space than the rendered text uses. On a crowded menubar that visibly stretches the codeburn entry relative to neighbours. The value already uses String(format: "\(symbol)%.2f", ...) at AppStore.swift:299-302, and the menubar title prepends a leading space at CodeBurnApp.swift:141 (" " + cost.asCompactCurrency()), so both the width reservation and the rendered string have room to tighten without touching the anchor-stability design.

Proposal

When compact mode is on:

  • Render "\(symbol)\(Int(cost * rate))" instead of " \(symbol)\(String(format: "%.2f", cost * rate))". Drops the leading space and the decimals. Example: 🔥$110.
  • Swap statusItem.length from statusItemFixedWidth (130 pt) to a smaller named constant. Exact value is your call; roughly 90 pt fits three-digit costs, ~100 pt covers four digits.

Both constants stay private let at module scope so nothing becomes a magic number.

Config surface (happy to defer to you)

Three routes, each with different tradeoffs. Flagging all three because the right answer depends on how you want the knob exposed:

Option Pros Cons
~/.config/codeburn/config.json field (e.g. menubar.compact: true) Consistent with the existing currency + plan crossing CLI and Swift (CurrencyState.swift:167-177); enables a codeburn menubar --compact subcommand; persists across reinstalls Adds a schema field; both CLI and Swift need updates
Hidden UserDefaults key (e.g. CodeBurnMenubarCompact) Zero new schema; matches existing UserDefaults state keys (UpdateChecker.*, codeburn.starBannerDismissed); Swift-only change Invisible to the CLI; not editable via codeburn subcommands
Visible Settings UI Standard macOS UX No precedent in the current app (Settings { EmptyView() } at CodeBurnApp.swift:20-22)

Happy with whichever you pick, or a different approach entirely.

Edge cases worth calling out

  • Four-digit costs: preference on clipping, widening the compact slot to ~100 pt, or a two-tier width (3-digit vs 4-digit)? I can implement whichever you prefer.
  • Findings badge: the comment at CodeBurnApp.swift:104-106 references findings badge width, but reading refreshStatusButton (lines 119-151) the current title only composes the flame attachment plus the cost value. findingsCount (AppStore.swift:51-53) is consumed by FindingsSection and HeatmapSection, not the menubar title. If that is correct, compact mode needs no findings-badge handling today. If I missed something, let me know and I will adjust.
  • Scope: this proposal is width and format only. No metric switching, no icon-only mode, no multi-currency formatting changes. Those would be separate issues if you want them at all.

Offer

Happy to send a PR on feat/menubar-compact once you greenlight an approach and pick a config surface. I will follow the contribution rules in CLAUDE.md (no emoji in code, no em dashes, no magic numbers, branch off main, no co-author lines).

Thanks for the tool; it is useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions