102 lines · 4.1 KB · Swift
RawDownload
import AppKitimport CodexBarCore extension StatusItemController {    func refreshProviderSelectionDependentUI(        refreshOpenMenus: Bool = false,        deferRendering: Bool = false)    {        #if DEBUG        guard !self.isReleasedForTesting else { return }        #endif        self.advanceMenuInteraction(for: self.mergedMenu)        self.invalidateMenus(refreshOpenMenus: refreshOpenMenus)        if deferRendering {            self.scheduleProviderSelectionUIRefresh()            return        }        self.refreshProviderSelectionRendering()    }     private func scheduleProviderSelectionUIRefresh() {        self.providerSelectionUIRefreshTask?.cancel()        self.providerSelectionUIRefreshTask = Task { @MainActor [weak self] in            await Task.yield()            guard !Task.isCancelled, let self else { return }            self.refreshProviderSelectionRendering()            self.providerSelectionUIRefreshTask = nil        }    }     private func refreshProviderSelectionRendering() {        self.updateAnimationState()        self.updateBlinkingState()        let phase: Double? = self.needsMenuBarIconAnimation() ? self.animationPhase : nil        self.applyIcon(phase: phase)    }     func navigateProviderSwitcher(        _ direction: StatusItemMenuProviderNavigationDirection,        menu: NSMenu? = nil)    {        guard self.shouldMergeIcons else { return }        let enabledProviders = self.store.enabledProvidersForDisplay()        guard enabledProviders.count > 1 else { return }         let includesOverview = !self.settings.resolvedMergedOverviewProviders(            activeProviders: enabledProviders,            maxVisibleProviders: SettingsStore.mergedOverviewProviderLimit).isEmpty        var selections = enabledProviders.map(ProviderSwitcherSelection.provider)        if includesOverview {            selections.insert(.overview, at: 0)        }         let current: ProviderSwitcherSelection = if includesOverview,                                                    self.settings.mergedMenuLastSelectedWasOverview        {            .overview        } else {            .provider(self.navigationResolvedProvider(enabledProviders: enabledProviders) ?? .codex)        }        guard let currentIndex = selections.firstIndex(of: current) else { return }         let delta = direction == .next ? 1 : -1        let nextIndex = (currentIndex + delta + selections.count) % selections.count        let selection = selections[nextIndex]        let menuProvider: UsageProvider = switch selection {        case .overview:            self.navigationResolvedProvider(enabledProviders: enabledProviders) ?? .codex        case let .provider(provider):            provider        }        self.preservingMergedSwitcherContentCachesDuringInvalidation {            switch selection {            case .overview:                self.settings.mergedMenuLastSelectedWasOverview = true                self.lastMenuProvider = self.navigationResolvedProvider(enabledProviders: enabledProviders) ?? .codex            case let .provider(provider):                self.settings.mergedMenuLastSelectedWasOverview = false                self.selectedMenuProvider = provider                self.lastMenuProvider = provider            }            self.lastMergedSwitcherSelection = selection            self.refreshProviderSelectionDependentUI(deferRendering: true)        }        let trackedMenu = menu ?? self.providerSwitcherShortcutMenuID.flatMap { self.openMenus[$0] }        if let trackedMenu {            self.requestProviderSwitcherMenuRebuild(                trackedMenu,                provider: menuProvider)        }    }     private func navigationResolvedProvider(enabledProviders: [UsageProvider]) -> UsageProvider? {        if enabledProviders.isEmpty {            return .codex        }        if let selected = self.selectedMenuProvider, enabledProviders.contains(selected) {            return selected        }        return enabledProviders.first(where: { self.store.isProviderAvailable($0) }) ?? enabledProviders.first    }}