45 lines · 1.4 KB · Swift
RawDownload
import CodexBarCoreimport Observation struct MenuCardLiveSubtitle {    let text: String    let style: UsageMenuCardView.Model.SubtitleStyle} /// Updates values in an already-hosted card without rebuilding its tracked NSMenu.@MainActor@Observablefinal class MenuCardRefreshMonitor {    typealias ModelResolver = @MainActor (UsageProvider) -> UsageMenuCardView.Model?     private let resolveModel: ModelResolver    var isManualRefreshInFlight = false     init(resolveModel: @escaping ModelResolver) {        self.resolveModel = resolveModel    }     func model(        for provider: UsageProvider,        fallback: UsageMenuCardView.Model) -> UsageMenuCardView.Model    {        guard !self.isManualRefreshInFlight,              let resolved = self.resolveModel(provider),              fallback.hasCompatibleTrackedLayout(with: resolved)        else {            return fallback        }        return resolved    }     func subtitle(        for provider: UsageProvider,        fallback: MenuCardLiveSubtitle) -> MenuCardLiveSubtitle    {        if self.isManualRefreshInFlight {            return MenuCardLiveSubtitle(text: "\(L("Refreshing"))…", style: .loading)        }        guard let model = self.resolveModel(provider) else { return fallback }        return MenuCardLiveSubtitle(text: model.subtitleText, style: model.subtitleStyle)    }}