Skip to content

Add option to show current date on status bar icon#922

Open
apomerenk wants to merge 5 commits intoleits:masterfrom
apomerenk:feat/show-date-on-icon
Open

Add option to show current date on status bar icon#922
apomerenk wants to merge 5 commits intoleits:masterfrom
apomerenk:feat/show-date-on-icon

Conversation

@apomerenk
Copy link
Copy Markdown

@apomerenk apomerenk commented Apr 28, 2026

Summary

  • Adds a new "Show today's date on icon" toggle in Preferences → Appearance → Status bar
  • When enabled, the current day-of-month is overlaid on the calendar status bar icon (both the iconCalendar and iconCalendarCheckmark variants), making the icon useful at a glance even when there are no upcoming events
  • The toggle is only available when the Calendar or Event-specific icon style is selected (disabled for the MeetingBar app icon and "No icon" options)

Closes #654

Implementation notes

  • New Defaults key showDateOnIcon (default false) — opt-in, no behavior change for existing users
  • New helper calendarIconWithOptionalDate(named:) in StatusBarItemController composites the day number onto the base icon and preserves its isTemplate flag so macOS continues to tint it correctly in light/dark menu bars
  • The status bar already redraws every minute via AppDelegate, so the date refreshes automatically at midnight without an extra timer
  • Localizable string added to en.lproj only — Weblate will pick up the new key for other locales

Test plan

  • Build in Xcode (could not verify locally — only command-line tools installed)
  • Toggle "Show today's date on icon" on/off in Preferences and confirm icon updates immediately
  • With toggle on and no upcoming events, confirm the day-of-month is visible on the calendar checkmark icon in both light and dark menu bars
  • With toggle on and an upcoming event with Calendar icon style, confirm the date appears on the iconCalendar
  • Confirm two-digit days (e.g., 28) render legibly within the icon body
  • Confirm toggle is disabled when "MeetingBar" app icon or "No icon" is selected

Summary by CodeRabbit

  • New Features

    • Added a preference toggle (off by default) to show today's date on the status bar icon.
    • Status bar icons can optionally display the current day when a calendar-themed icon is selected; toggle is disabled for app-icon or no-icon choices.
  • Localization

    • Added English text for the new preference label.
  • Refactor

    • Simplified icon rendering to centralize calendar/date composition.
  • Tests

    • Added unit tests validating calendar-icon composition and behavior.

Adds a 'Show today's date on icon' toggle in Appearance preferences that
overlays the current day-of-month number on the calendar status bar icon.
Useful when there are no upcoming events and the icon would otherwise be
visually empty (closes leits#654).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Apr 28, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 9f12466d-119b-4dea-9336-9653ad583184

📥 Commits

Reviewing files that changed from the base of the PR and between 6b40ef4 and 698c703.

📒 Files selected for processing (2)
  • MeetingBar/UI/StatusBar/StatusBarItemController.swift
  • MeetingBarTests/StatusBarItem/CalendarIconTests.swift

Walkthrough

Adds a new Boolean preference showDateOnIcon, English localization, a Preferences toggle (conditionally disabled), status bar rendering updates to optionally overlay the current day-of-month onto calendar-style icons, and unit tests for the composed calendar icon.

Changes

Cohort / File(s) Summary
Defaults & Localization
MeetingBar/Extensions/DefaultsKeys.swift, MeetingBar/Resources/Localization/en.lproj/Localizable.strings
Added showDateOnIcon Defaults key (Key<Bool>("showDateOnIcon", default: false)) and English localization preferences_appearance_status_bar_show_date_on_icon.
Status Bar Rendering
MeetingBar/UI/StatusBar/StatusBarItemController.swift
Status bar now observes showDateOnIcon; icon selection uses calendarIconWithOptionalDate(named:) and a new makeCalendarIcon(...) helper to compose calendar icons and optionally overlay the day-of-month.
Preferences UI
MeetingBar/UI/Views/Preferences/AppearanceTab.swift
Added a toggle bound to .showDateOnIcon; toggle is disabled when icon format is .appicon or .none.
Tests
MeetingBarTests/StatusBarItem/CalendarIconTests.swift
New XCTest suite validating makeCalendarIcon behavior (no-op conditions, composed image creation, size/isTemplate preservation, two-digit day handling).

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant User as "User"
    participant PrefsUI as "Preferences UI"
    participant Defaults as "Defaults Store"
    participant StatusBar as "StatusBarItemController"
    participant Renderer as "Icon Renderer"

    User->>PrefsUI: Toggle "Show date on icon"
    PrefsUI->>Defaults: Set `showDateOnIcon`
    Defaults->>StatusBar: Publish change
    StatusBar->>Renderer: Request icon for current format
    Renderer->>Renderer: Load base calendar image
    alt showDateOnIcon = true and format allows
        Renderer->>Renderer: Compose calendar image + overlay day text
    else
        Renderer->>Renderer: Return base image unchanged
    end
    Renderer-->>StatusBar: Return image
    StatusBar->>StatusBar: Update menu bar item
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

lgtm

Suggested reviewers

  • leits

Poem

🐰 I hopped into the menu bar bright,
and painted today's number on a tiny light,
snug in the square, bold and clear,
toggle me on to see the day appear,
hop—now the date is dancing here.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main feature: adding an option to display the current date on the status bar icon.
Linked Issues check ✅ Passed The PR fully implements all coding requirements from issue #654: opt-in date display on calendar icon, limit to appropriate icon styles, and proper icon composition.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the date-on-icon feature: new Defaults key, localization string, UI toggle, icon rendering logic, and unit tests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@dosubot dosubot Bot added the feature New feature or request label Apr 28, 2026
Helper was returning NSImage? but call site at line 244 assigns to
NSImage. The base NSImage(named:) was already force-unwrapped by the
existing code, so make the helper return non-optional to match.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 28, 2026

Codecov Report

❌ Patch coverage is 67.58621% with 47 lines in your changes missing coverage. Please review.
✅ Project coverage is 37.10%. Comparing base (69bf18d) to head (698c703).
⚠️ Report is 8 commits behind head on master.

Files with missing lines Patch % Lines
...tingBar/UI/StatusBar/StatusBarItemController.swift 2.43% 40 Missing ⚠️
...eetingBar/UI/Views/Preferences/AppearanceTab.swift 0.00% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #922      +/-   ##
==========================================
+ Coverage   36.26%   37.10%   +0.84%     
==========================================
  Files          48       49       +1     
  Lines        5129     5271     +142     
  Branches     1743     1751       +8     
==========================================
+ Hits         1860     1956      +96     
- Misses       3213     3258      +45     
- Partials       56       57       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
MeetingBar/UI/StatusBar/StatusBarItemController.swift (1)

529-563: Verify the composed icon stays crisp on Retina displays.

lockFocus() flattens the asset into a single composed bitmap, so this may drop higher-resolution reps and soften the status-bar icon on high-DPI screens. Please verify the visual result; if it regresses, consider a composition path that preserves the source image representations.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@MeetingBar/UI/StatusBar/StatusBarItemController.swift` around lines 529 -
563, The composed calendar icon created in calendarIconWithOptionalDate
currently uses lockFocus which flattens representations and can soften Retina
assets; replace the lockFocus approach with explicit high-resolution bitmap
composition: create an NSBitmapImageRep sized using the current backing scale
(e.g., backingScale = NSScreen.main?.backingScaleFactor ?? 1.0, pixelsWide =
Int(size.width * backingScale), pixelsHigh = Int(size.height * backingScale)),
add that NSBitmapImageRep to a new NSImage (the composed image), set up an
NSGraphicsContext with that bitmap (NSGraphicsContext(bitmapImageRep:)), draw
baseImage into the context using
draw(in:from:operation:fraction:respectFlipped:hints:) (so the image uses its
bestRepresentation), draw the date string with imageInterpolation = .high and
correct font scaling for the scale factor, remove lockFocus usage on composed
and ensure composed.isTemplate is set from baseImage.isTemplate before
returning.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@MeetingBar/UI/StatusBar/StatusBarItemController.swift`:
- Around line 529-563: The composed calendar icon created in
calendarIconWithOptionalDate currently uses lockFocus which flattens
representations and can soften Retina assets; replace the lockFocus approach
with explicit high-resolution bitmap composition: create an NSBitmapImageRep
sized using the current backing scale (e.g., backingScale =
NSScreen.main?.backingScaleFactor ?? 1.0, pixelsWide = Int(size.width *
backingScale), pixelsHigh = Int(size.height * backingScale)), add that
NSBitmapImageRep to a new NSImage (the composed image), set up an
NSGraphicsContext with that bitmap (NSGraphicsContext(bitmapImageRep:)), draw
baseImage into the context using
draw(in:from:operation:fraction:respectFlipped:hints:) (so the image uses its
bestRepresentation), draw the date string with imageInterpolation = .high and
correct font scaling for the scale factor, remove lockFocus usage on composed
and ensure composed.isTemplate is set from baseImage.isTemplate before
returning.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 615b0c08-63c1-49b7-8006-b23d066185b1

📥 Commits

Reviewing files that changed from the base of the PR and between 6a088d3 and 1fa725c.

📒 Files selected for processing (4)
  • MeetingBar/Extensions/DefaultsKeys.swift
  • MeetingBar/Resources /Localization /en.lproj/Localizable.strings
  • MeetingBar/UI/StatusBar/StatusBarItemController.swift
  • MeetingBar/UI/Views/Preferences/AppearanceTab.swift

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@MeetingBar/UI/StatusBar/StatusBarItemController.swift`:
- Around line 529-533: The function calendarIconWithOptionalDate currently only
checks Defaults[.showDateOnIcon], so dates still get overlaid when the user has
set the icon format to .none; update calendarIconWithOptionalDate to also gate
the overlay by the icon format (e.g. check Defaults[.iconFormat] != .none) and
return the baseImage early if the icon format is .none, keeping the existing
Defaults[.showDateOnIcon] check and the rest of the overlay logic unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 134c276e-a4a0-495b-b51d-21adf2ddf940

📥 Commits

Reviewing files that changed from the base of the PR and between 1fa725c and 3bb83dc.

📒 Files selected for processing (1)
  • MeetingBar/UI/StatusBar/StatusBarItemController.swift

Comment thread MeetingBar/UI/StatusBar/StatusBarItemController.swift Outdated
apomerenk and others added 2 commits April 28, 2026 10:16
Address CodeRabbit feedback: the showDateOnIcon toggle is UI-disabled
for the .none and .appicon formats, but the saved Bool would still
trigger an overlay on fallback calendar icons drawn from those code
paths. Match the toggle's disabled-state intent by also requiring the
icon format to be .calendar or .eventtype before compositing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extract the icon-compositing logic from StatusBarItemController into a
free function (makeCalendarIcon) so it can be tested without spinning up
the @mainactor controller. Adds coverage for:
- guard returns base image when showDate is false
- guard returns base image when icon format is .appicon or .none
- composed image is produced for .calendar and .eventtype formats
- isTemplate flag propagates from base to composed image
- two-digit day rendering does not crash

Addresses the codecov/patch coverage gap on PR leits#922.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels Apr 28, 2026
size: iconSize
)
XCTAssertEqual(result.size, iconSize)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Show the date on the icon

2 participants