diff --git a/Sources/AppDelegate.swift b/Sources/AppDelegate.swift index d967f6e..bf03572 100644 --- a/Sources/AppDelegate.swift +++ b/Sources/AppDelegate.swift @@ -38,7 +38,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate { button.action = #selector(togglePopover) button.target = self } - updateBadge(count: bugStore.unseenActiveCount) + updateBadge(count: bugStore.activeBugs.count) } private func setupPopover() { diff --git a/Sources/Services/PollerService.swift b/Sources/Services/PollerService.swift index 39d1fc4..d6839eb 100644 --- a/Sources/Services/PollerService.swift +++ b/Sources/Services/PollerService.swift @@ -76,7 +76,7 @@ final class PollerService { await MainActor.run { bugStore.update(with: bugs) bugStore.setLoading(false) - AppDelegate.shared?.updateBadge(count: bugStore.unseenActiveCount) + AppDelegate.shared?.updateBadge(count: bugStore.activeBugs.count) } } catch FeishuError.unauthorized { await MainActor.run { diff --git a/Sources/Utils/URL+Feishu.swift b/Sources/Utils/URL+Feishu.swift index aa2b223..b0001b8 100644 --- a/Sources/Utils/URL+Feishu.swift +++ b/Sources/Utils/URL+Feishu.swift @@ -7,7 +7,8 @@ enum FeishuURLBuilder { tableId: String, recordId: String ) -> URL { - URL(string: "https://\(baseDomain)/base/\(appToken)/table/\(tableId)/record/\(recordId)")! + // Feishu Bitable record deep link: uses query parameters + URL(string: "https://\(baseDomain)/base/\(appToken)?table=\(tableId)&record=\(recordId)")! } static func tableURL(baseDomain: String, appToken: String) -> URL { diff --git a/Sources/Views/FloatingWidget/FloatingWidgetWindow.swift b/Sources/Views/FloatingWidget/FloatingWidgetWindow.swift index 36f1bd3..7d2d6bd 100644 --- a/Sources/Views/FloatingWidget/FloatingWidgetWindow.swift +++ b/Sources/Views/FloatingWidget/FloatingWidgetWindow.swift @@ -4,7 +4,7 @@ import SwiftUI final class FloatingWidgetWindow: NSPanel { init() { super.init( - contentRect: NSRect(x: 0, y: 0, width: 80, height: 60), + contentRect: NSRect(x: 0, y: 0, width: 140, height: 70), styleMask: [.borderless, .nonactivatingPanel], backing: .buffered, defer: false @@ -35,22 +35,47 @@ final class FloatingWidgetWindow: NSPanel { struct FloatingWidgetView: View { @State private var bugStore = BugStore.shared + private var priorityCounts: [(BugPriority, Int)] { + let active = bugStore.activeBugs + return BugPriority.allCases + .filter { $0 != .unknown } + .map { priority in + (priority, active.filter { $0.priority == priority }.count) + } + .filter { $0.1 > 0 } + } + var body: some View { Button { AppDelegate.shared?.togglePopover() } label: { - HStack(spacing: 6) { - Image(systemName: "ant.fill") - .font(.title3) - Text("\(bugStore.unseenActiveCount)") - .font(.title2) - .fontWeight(.bold) - .contentTransition(.numericText()) + VStack(spacing: 4) { + HStack(spacing: 4) { + Image(systemName: "ant.fill") + .font(.caption) + Text("\(bugStore.activeBugs.count)") + .font(.title3) + .fontWeight(.bold) + } + if !priorityCounts.isEmpty { + HStack(spacing: 6) { + ForEach(priorityCounts, id: \.0) { priority, count in + HStack(spacing: 2) { + Circle() + .fill(priority.color) + .frame(width: 6, height: 6) + Text("\(count)") + .font(.caption2) + .fontWeight(.medium) + } + } + } + } } - .padding(.horizontal, 12) - .padding(.vertical, 8) + .padding(.horizontal, 14) + .padding(.vertical, 10) .background( - RoundedRectangle(cornerRadius: 12) + RoundedRectangle(cornerRadius: 14) .fill(.ultraThinMaterial) .shadow(color: .black.opacity(0.15), radius: 8, x: 0, y: 4) ) diff --git a/Sources/Views/MenuBar/BugListPopover.swift b/Sources/Views/MenuBar/BugListPopover.swift index 6b73a2c..18215d6 100644 --- a/Sources/Views/MenuBar/BugListPopover.swift +++ b/Sources/Views/MenuBar/BugListPopover.swift @@ -35,7 +35,7 @@ struct BugListPopover: View { } Button("Mark all seen") { bugStore.markAllSeen() - AppDelegate.shared?.updateBadge(count: bugStore.unseenActiveCount) + AppDelegate.shared?.updateBadge(count: bugStore.activeBugs.count) } .font(.caption) } @@ -62,7 +62,7 @@ struct BugListPopover: View { .onTapGesture { openInFeishu(bug) bugStore.markSeen(bug.id) - AppDelegate.shared?.updateBadge(count: bugStore.unseenActiveCount) + AppDelegate.shared?.updateBadge(count: bugStore.activeBugs.count) } Divider().padding(.leading, 44) }