Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,14 @@ jobs:
--skip CodexUsageFetcherFallbackTests \
--skip CodexWebDashboardStrategyAuthorityTests \
--skip OpenAIDashboardNavigationDelegateTests \
--skip StatusMenuCodexSwitcherTests \
--skip StatusMenuHostedSubmenuRefreshTests \
--skip StatusMenuSwitcherClickTests \
--skip StatusMenuTests \
--skip StatusMenuTokenAccountSwitcherTests \
--skip SubprocessRunnerTests
swift test --no-parallel \
--filter 'ClaudeOAuthCredentialsStoreSecurityCLITests|CLIOpenAIDashboardCacheTests|CodexAccountScopedRefreshDashboardCleanupTests|CodexAccountScopedRefreshTests|CodexBaselineCharacterizationTests|CodexDashboardWorkedExampleParityTests|CodexUsageFetcherFallbackTests|CodexWebDashboardStrategyAuthorityTests|OpenAIDashboardNavigationDelegateTests|SubprocessRunnerTests'
--filter 'ClaudeOAuthCredentialsStoreSecurityCLITests|CLIOpenAIDashboardCacheTests|CodexAccountScopedRefreshDashboardCleanupTests|CodexAccountScopedRefreshTests|CodexBaselineCharacterizationTests|CodexDashboardWorkedExampleParityTests|CodexUsageFetcherFallbackTests|CodexWebDashboardStrategyAuthorityTests|OpenAIDashboardNavigationDelegateTests|StatusMenuCodexSwitcherTests|StatusMenuHostedSubmenuRefreshTests|StatusMenuSwitcherClickTests|StatusMenuTests|SubprocessRunnerTests'

build-linux-cli:
timeout-minutes: 20
Expand Down
22 changes: 18 additions & 4 deletions Sources/CodexBar/PreferencesDisplayPane.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,24 @@ struct DisplayPane: View {
title: L("show_credits_extra_usage_title"),
subtitle: L("show_credits_extra_usage_subtitle"),
binding: self.$settings.showOptionalCreditsAndExtraUsage)
PreferenceToggleRow(
title: L("show_all_token_accounts_title"),
subtitle: L("show_all_token_accounts_subtitle"),
binding: self.$settings.showAllTokenAccountsInMenu)
HStack(alignment: .top, spacing: 12) {
VStack(alignment: .leading, spacing: 4) {
Text(L("multi_account_layout_title"))
.font(.body)
Text(L("multi_account_layout_subtitle"))
.font(.footnote)
.foregroundStyle(.tertiary)
}
Spacer()
Picker(L("multi_account_layout_title"), selection: self.$settings.multiAccountMenuLayout) {
ForEach(MultiAccountMenuLayout.allCases) { layout in
Text(layout.label).tag(layout)
}
}
.labelsHidden()
.pickerStyle(.menu)
.frame(maxWidth: 200)
}
self.overviewProviderSelector
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,11 @@ extension UsageStore {
errorOverride: String? = nil,
now: Date = Date()) -> CodexConsumerProjection
{
let snapshot = surface == .overrideCard ? snapshotOverride : snapshotOverride ?? self.snapshots[.codex]
let rawUsageError = surface == .overrideCard ? errorOverride : errorOverride ?? self.errors[.codex]
let context = CodexConsumerProjection.Context(
snapshot: snapshotOverride ?? self.snapshots[.codex],
rawUsageError: errorOverride ?? self.errors[.codex],
snapshot: snapshot,
rawUsageError: rawUsageError,
liveCredits: self.credits,
rawCreditsError: self.lastCreditsError,
liveDashboard: self.openAIDashboard,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ extension UsageStore {
self.lastSourceLabels.removeValue(forKey: .codex)
self.lastFetchAttempts.removeValue(forKey: .codex)
self.accountSnapshots.removeValue(forKey: .codex)
self.codexAccountSnapshots = []
self.failureGates[.codex]?.reset()
self.lastKnownSessionRemaining.removeValue(forKey: .codex)
self.lastKnownSessionWindowSource.removeValue(forKey: .codex)
Expand Down
4 changes: 4 additions & 0 deletions Sources/CodexBar/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,10 @@
"show_credits_extra_usage_subtitle" = "Show Codex Credits and Claude Extra usage sections in the menu.";
"show_all_token_accounts_title" = "Show all token accounts";
"show_all_token_accounts_subtitle" = "Stack token accounts in the menu (otherwise show an account switcher bar).";
"multi_account_layout_title" = "Multi-account layout";
"multi_account_layout_subtitle" = "Choose segmented account switching or stacked account cards.";
"multi_account_layout_segmented" = "Segmented";
"multi_account_layout_stacked" = "Stacked";
"overview_tab_providers_title" = "Overview tab providers";
"configure" = "Configure…";
"overview_enable_merge_icons_hint" = "Enable Merge Icons to configure Overview tab providers.";
Expand Down
4 changes: 4 additions & 0 deletions Sources/CodexBar/Resources/zh-Hans.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,10 @@
"show_credits_extra_usage_subtitle" = "在菜单中显示 Codex 积分和 Claude 额外用量部分。";
"show_all_token_accounts_title" = "显示所有令牌账户";
"show_all_token_accounts_subtitle" = "在菜单中堆叠令牌账户(否则显示账户切换栏)。";
"multi_account_layout_title" = "多账户布局";
"multi_account_layout_subtitle" = "选择分段账户切换或堆叠账户卡片。";
"multi_account_layout_segmented" = "分段";
"multi_account_layout_stacked" = "堆叠";
"overview_tab_providers_title" = "概览标签提供商";
"configure" = "配置…";
"overview_enable_merge_icons_hint" = "启用合并图标以配置概览标签提供商。";
Expand Down
13 changes: 9 additions & 4 deletions Sources/CodexBar/SettingsStore+Defaults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,19 @@ extension SettingsStore {
set { self.menuBarDisplayModeRaw = newValue.rawValue }
}

var showAllTokenAccountsInMenu: Bool {
get { self.defaultsState.showAllTokenAccountsInMenu }
var multiAccountMenuLayout: MultiAccountMenuLayout {
get { MultiAccountMenuLayout(rawValue: self.defaultsState.multiAccountMenuLayoutRaw) ?? .segmented }
set {
self.defaultsState.showAllTokenAccountsInMenu = newValue
self.userDefaults.set(newValue, forKey: "showAllTokenAccountsInMenu")
self.defaultsState.multiAccountMenuLayoutRaw = newValue.rawValue
self.userDefaults.set(newValue.rawValue, forKey: "multiAccountMenuLayout")
}
}

var showAllTokenAccountsInMenu: Bool {
get { self.multiAccountMenuLayout == .stacked }
set { self.multiAccountMenuLayout = newValue ? .stacked : .segmented }
}

var historicalTrackingEnabled: Bool {
get { self.defaultsState.historicalTrackingEnabled }
set {
Expand Down
2 changes: 1 addition & 1 deletion Sources/CodexBar/SettingsStore+MenuObservation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ extension SettingsStore {
_ = self.menuBarShowsHighestUsage
_ = self.menuBarDisplayMode
_ = self.historicalTrackingEnabled
_ = self.showAllTokenAccountsInMenu
_ = self.multiAccountMenuLayout
_ = self.menuBarMetricPreferencesRaw
_ = self.costUsageEnabled
_ = self.hidePersonalInfo
Expand Down
23 changes: 21 additions & 2 deletions Sources/CodexBar/SettingsStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,22 @@ enum MenuBarMetricPreference: String, CaseIterable, Identifiable {
}
}

enum MultiAccountMenuLayout: String, CaseIterable, Identifiable {
case segmented
case stacked

var id: String {
self.rawValue
}

var label: String {
switch self {
case .segmented: L("multi_account_layout_segmented")
case .stacked: L("multi_account_layout_stacked")
}
}
}

@MainActor
@Observable
final class SettingsStore {
Expand Down Expand Up @@ -279,7 +295,10 @@ extension SettingsStore {
let menuBarDisplayModeRaw = userDefaults.string(forKey: "menuBarDisplayMode")
?? MenuBarDisplayMode.percent.rawValue
let historicalTrackingEnabled = userDefaults.object(forKey: "historicalTrackingEnabled") as? Bool ?? false
let showAllTokenAccountsInMenu = userDefaults.object(forKey: "showAllTokenAccountsInMenu") as? Bool ?? false
let multiAccountMenuLayoutRaw = userDefaults.string(forKey: "multiAccountMenuLayout") ?? {
let legacyShowAll = userDefaults.object(forKey: "showAllTokenAccountsInMenu") as? Bool ?? false
return legacyShowAll ? MultiAccountMenuLayout.stacked.rawValue : MultiAccountMenuLayout.segmented.rawValue
}()
let storedPreferences = userDefaults.dictionary(forKey: "menuBarMetricPreferences") as? [String: String] ?? [:]
var resolvedPreferences = storedPreferences
if resolvedPreferences.isEmpty,
Expand Down Expand Up @@ -351,7 +370,7 @@ extension SettingsStore {
menuBarShowsBrandIconWithPercent: menuBarShowsBrandIconWithPercent,
menuBarDisplayModeRaw: menuBarDisplayModeRaw,
historicalTrackingEnabled: historicalTrackingEnabled,
showAllTokenAccountsInMenu: showAllTokenAccountsInMenu,
multiAccountMenuLayoutRaw: multiAccountMenuLayoutRaw,
menuBarMetricPreferencesRaw: resolvedPreferences,
costUsageEnabled: costUsageEnabled,
hidePersonalInfo: hidePersonalInfo,
Expand Down
2 changes: 1 addition & 1 deletion Sources/CodexBar/SettingsStoreState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct SettingsDefaultsState {
var menuBarShowsBrandIconWithPercent: Bool
var menuBarDisplayModeRaw: String?
var historicalTrackingEnabled: Bool
var showAllTokenAccountsInMenu: Bool
var multiAccountMenuLayoutRaw: String
var menuBarMetricPreferencesRaw: [String: String]
var costUsageEnabled: Bool
var hidePersonalInfo: Bool
Expand Down
Loading