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
9 changes: 6 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ Use this sequence for feature and fix work:
3. Implementation: keep changes scoped and buildable.
4. Testing: run the narrowest useful checks, then broader checks when shared behavior changes.
5. Documentation: update changelogs, release notes, and research status as needed.
6. Commit: bump iOS build numbers only when preparing a Git commit for push.
7. Release: archive/upload only when explicitly requested.
6. Commit: keep build numbers unchanged for ordinary branch or PR commits.
7. Release: bump iOS build numbers only when preparing an actual TestFlight/App Store build; archive/upload only when explicitly requested.

## iOS Documentation Rules

Expand All @@ -44,13 +44,16 @@ Do not push to `upstream`. Push QuotaKit work to `origin`, which is `https://git

## iOS Build Numbers

When preparing a pushed iOS change:
When preparing an actual iOS build for TestFlight or App Store distribution:

1. Open `CodexBarMobile/project.yml`.
2. Increment every `CURRENT_PROJECT_VERSION` value by 1.
3. Do not change `MARKETING_VERSION` unless explicitly requested.
4. Run `cd CodexBarMobile && xcodegen generate`.

Do not bump build numbers for routine local commits, review branches, PR updates,
or merges that are not being archived/uploaded as a new iOS build.

## Localization

The current iOS build pipeline requires every new user-facing `String(localized:)` key to be present in `CodexBarMobile/CodexBarMobile/Localizable.xcstrings` for all supported app locales, with every entry marked `translated`.
Expand Down
3 changes: 3 additions & 0 deletions CodexBarMobile/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ current Columbus Labs product surface and recent release history.
stale threshold).
- Sync freshness chips now tick live, can be tapped to refresh, and keep showing
refreshing or failed-refresh state after pull-to-refresh releases.
- Provider tints now mirror the Mac registry without near-collisions, stay
readable in light and dark appearances, and keep synced-time VoiceOver status
intact when the chip is tappable.
- Added public Columbus Labs remote config guardrails for safe setup-link overrides,
announcements, and feature kill switches. Native app changes still require a
TestFlight/App Store build.
Expand Down
57 changes: 36 additions & 21 deletions CodexBarMobile/CodexBarMobile/ContentView.swift

Large diffs are not rendered by default.

29 changes: 27 additions & 2 deletions CodexBarMobile/CodexBarMobile/Design/SyncFreshnessChip.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,17 @@ enum SyncFreshnessFormatter {
}
}

enum SyncFreshnessTimeline {
static func cadence(since timestamp: Date?, now: Date = Date()) -> TimeInterval {
guard let timestamp else { return 60 }
let interval = max(0, now.timeIntervalSince(timestamp))
if interval < 60 { return 1 }
if interval < 3600 { return 60 }
if interval < 86400 { return 300 }
return 3600
}
}

struct SyncStatusChipView: View {
let placement: SyncFreshnessPlacement
let isDemoMode: Bool
Expand All @@ -132,8 +143,22 @@ struct SyncStatusChipView: View {
return false
}

private var timelineReferenceDate: Date? {
switch self.syncStatus {
case .synced(let lastConfirmedSync):
lastConfirmedSync
case .syncing, .error:
self.snapshot?.syncTimestamp
case .noData, .incompatibleData:
self.snapshot?.syncTimestamp
}
}

var body: some View {
TimelineView(.periodic(from: .now, by: 1)) { timeline in
TimelineView(.periodic(
from: .now,
by: SyncFreshnessTimeline.cadence(since: self.timelineReferenceDate)))
{ timeline in
if let state = SyncFreshnessState.resolve(
isDemoMode: self.isDemoMode,
snapshot: self.snapshot,
Expand Down Expand Up @@ -164,7 +189,7 @@ struct SyncStatusChipView: View {
}
.buttonStyle(.plain)
.disabled(self.isRefreshing)
.accessibilityLabel(Text("Refresh synced data"))
.accessibilityHint(Text("Refresh synced data"))
} else {
content()
}
Expand Down
Loading