diff --git a/ClaudeChecker/Info.plist b/ClaudeChecker/Info.plist index 84b7dd2..b3be0ff 100644 --- a/ClaudeChecker/Info.plist +++ b/ClaudeChecker/Info.plist @@ -15,9 +15,9 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.0.9 + 2.0.10 CFBundleVersion - 16 + 17 LSMinimumSystemVersion 13.0 LSUIElement diff --git a/ClaudeChecker/UpdateNotificationWindow.swift b/ClaudeChecker/UpdateNotificationWindow.swift index 9bfcb55..a060d18 100644 --- a/ClaudeChecker/UpdateNotificationWindow.swift +++ b/ClaudeChecker/UpdateNotificationWindow.swift @@ -21,14 +21,14 @@ class UpdateNotificationWindowController: NSWindowController { let icon = percent >= 95 ? "exclamationmark.circle.fill" : "exclamationmark.triangle.fill" let color = percent >= 95 ? Color.red : Color.orange let title = "Claude \(windowName) limit at \(percent)%" - let body = percent >= 95 ? "Almost out of quota — usage is critically high." : "Approaching your quota limit." + let body = percent >= 95 ? "Almost out of quota." : "Approaching your limit." showLimitWindow(title: title, subtitle: body, badgeIcon: icon, badgeColor: color, near: statusItem) } static func showLimitReset(windowName: String, near statusItem: NSStatusItem?) { showLimitWindow( title: "Claude \(windowName) limit reset", - subtitle: "Your quota has been reset — you're good to go.", + subtitle: "Your quota has been reset.", badgeIcon: "arrow.clockwise.circle.fill", badgeColor: .green, near: statusItem @@ -65,9 +65,13 @@ class UpdateNotificationWindowController: NSWindowController { } private static func makeWindow(content: V) -> UpdateNotificationWindowController { - let hosting = NSHostingController(rootView: content) + let hostingView = NSHostingView(rootView: content) + hostingView.frame = NSRect(x: 0, y: 0, width: 340, height: 1000) + let height = max(80, hostingView.fittingSize.height) + let size = NSSize(width: 340, height: height) + let window = NSWindow( - contentRect: NSRect(x: 0, y: 0, width: 340, height: 80), + contentRect: NSRect(origin: .zero, size: size), styleMask: [.borderless, .nonactivatingPanel], backing: .buffered, defer: false @@ -76,7 +80,8 @@ class UpdateNotificationWindowController: NSWindowController { window.backgroundColor = .clear window.level = .statusBar window.hasShadow = false - window.contentViewController = hosting + hostingView.frame = NSRect(origin: .zero, size: size) + window.contentView = hostingView return UpdateNotificationWindowController(window: window) } @@ -86,9 +91,9 @@ class UpdateNotificationWindowController: NSWindowController { let screen = buttonWindow.screen { let buttonFrame = buttonWindow.convertToScreen(button.frame) let x = buttonFrame.midX - 170 - // Stack below the update notification if it's showing - let yOffset: CGFloat = existingWindow != nil ? 80 + 8 + 8 : 8 - let y = buttonFrame.minY - 80 - yOffset + let h = window.frame.height + let yOffset: CGFloat = existingWindow.map { $0.frame.height + 8 } ?? 0 + let y = buttonFrame.minY - h - 8 - yOffset let clampedX = max(8, min(x, screen.frame.maxX - 348)) window.setFrameOrigin(NSPoint(x: clampedX, y: y)) } else { @@ -157,10 +162,10 @@ struct UpdateNotificationView: View { Text(subtitle) .font(.system(size: 11)) .foregroundColor(.secondary) - .lineLimit(1) + .fixedSize(horizontal: false, vertical: true) } - Spacer() + Spacer(minLength: 8) Button(action: onDismiss) { Image(systemName: "xmark") @@ -171,7 +176,7 @@ struct UpdateNotificationView: View { } .padding(.horizontal, 14) .padding(.vertical, 14) - .frame(width: 340, height: 80) + .frame(width: 340, alignment: .leading) .background( RoundedRectangle(cornerRadius: 13) .fill(Color(nsColor: .windowBackgroundColor)) diff --git a/README.md b/README.md index fe3130e..9a8b188 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![macOS](https://img.shields.io/badge/macOS-13.0+-000000?style=flat&logo=apple&logoColor=white)](https://www.apple.com/macos/) [![Swift](https://img.shields.io/badge/Swift-5.9-F05138?style=flat&logo=swift&logoColor=white)](https://swift.org) -[![Version](https://img.shields.io/badge/version-2.0.9-orange?style=flat)](https://github.com/superdooper86/claudechecker/releases) +[![Version](https://img.shields.io/badge/version-2.0.10-orange?style=flat)](https://github.com/superdooper86/claudechecker/releases) [![License](https://img.shields.io/badge/license-MIT-blue?style=flat)](LICENSE) @@ -36,6 +36,14 @@ No API key required. It reads directly from your `claude.ai` session using a bui Update banner
Update available Update notification
System notification + + 80% limit warning
80% limit warning + 95% limit warning
95% limit warning + + + Limit reset
Limit reset + +
diff --git a/screenshots/notif-limit-80.png b/screenshots/notif-limit-80.png new file mode 100644 index 0000000..7d543cc Binary files /dev/null and b/screenshots/notif-limit-80.png differ diff --git a/screenshots/notif-limit-95.png b/screenshots/notif-limit-95.png new file mode 100644 index 0000000..8c64490 Binary files /dev/null and b/screenshots/notif-limit-95.png differ diff --git a/screenshots/notif-reset.png b/screenshots/notif-reset.png new file mode 100644 index 0000000..94ebc4d Binary files /dev/null and b/screenshots/notif-reset.png differ diff --git a/version.json b/version.json index f4dc77d..dd8a137 100644 --- a/version.json +++ b/version.json @@ -1,5 +1,5 @@ { - "version": "2.0.9", - "url": "https://github.com/superdooper86/claudechecker/releases/download/v2.0.9/ClaudeChecker.zip", - "notes": "Added limit notifications: warns at 80% and 95% usage, and notifies when a limit resets." + "version": "2.0.10", + "url": "https://github.com/superdooper86/claudechecker/releases/download/v2.0.10/ClaudeChecker.zip", + "notes": "Limit notifications: warns at 80% and 95% usage, and notifies when a limit resets." }