fix: resolve compiler warnings across codebase

- PaywallView: remove unnecessary nil coalescing for currencyCode
- GameDAGRouter: change var to let for immutable compositeKeys
- GamesHistoryRow/View: add missing wnba and nwsl switch cases
- VisitDetailView: fix unused variable in preview
- AchievementEngine: use convenience init to avoid default parameter warning
- ProgressCardGenerator: use method overload instead of default parameter
- StadiumProximityMatcher: extract constants to ProximityConstants enum

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-01-13 13:16:40 -06:00
parent 22772fa57f
commit 04b62f147e
8 changed files with 33 additions and 15 deletions

View File

@@ -33,11 +33,16 @@ final class AchievementEngine {
// MARK: - Initialization // MARK: - Initialization
init(modelContext: ModelContext, dataProvider: AppDataProvider = AppDataProvider.shared) { init(modelContext: ModelContext, dataProvider: AppDataProvider) {
self.modelContext = modelContext self.modelContext = modelContext
self.dataProvider = dataProvider self.dataProvider = dataProvider
} }
/// Convenience initializer using the shared data provider
convenience init(modelContext: ModelContext) {
self.init(modelContext: modelContext, dataProvider: AppDataProvider.shared)
}
// MARK: - Public API // MARK: - Public API
/// Full recalculation (call after visit deleted or on app update) /// Full recalculation (call after visit deleted or on app update)

View File

@@ -212,18 +212,22 @@ struct PhotoMatchConfidence: Sendable {
} }
} }
// MARK: - Proximity Constants
/// Configuration constants for stadium proximity matching (outside @MainActor for default parameter use)
enum ProximityConstants: Sendable {
static let highConfidenceRadius: CLLocationDistance = 500 // 500m
static let mediumConfidenceRadius: CLLocationDistance = 2000 // 2km
static let searchRadius: CLLocationDistance = 5000 // 5km default
static let dateToleranceDays: Int = 1 // ±1 day for timezone/tailgating
}
// MARK: - Stadium Proximity Matcher // MARK: - Stadium Proximity Matcher
@MainActor @MainActor
final class StadiumProximityMatcher { final class StadiumProximityMatcher {
static let shared = StadiumProximityMatcher() static let shared = StadiumProximityMatcher()
// Configuration constants
static let highConfidenceRadius: CLLocationDistance = 500 // 500m
static let mediumConfidenceRadius: CLLocationDistance = 2000 // 2km
static let searchRadius: CLLocationDistance = 5000 // 5km default
static let dateToleranceDays: Int = 1 // ±1 day for timezone/tailgating
private let dataProvider = AppDataProvider.shared private let dataProvider = AppDataProvider.shared
private init() {} private init() {}
@@ -233,7 +237,7 @@ final class StadiumProximityMatcher {
/// Find stadiums within radius of coordinates /// Find stadiums within radius of coordinates
func findNearbyStadiums( func findNearbyStadiums(
coordinates: CLLocationCoordinate2D, coordinates: CLLocationCoordinate2D,
radius: CLLocationDistance = StadiumProximityMatcher.searchRadius, radius: CLLocationDistance = ProximityConstants.searchRadius,
sport: Sport? = nil sport: Sport? = nil
) -> [StadiumMatch] { ) -> [StadiumMatch] {
let photoLocation = CLLocation(latitude: coordinates.latitude, longitude: coordinates.longitude) let photoLocation = CLLocation(latitude: coordinates.latitude, longitude: coordinates.longitude)
@@ -275,7 +279,7 @@ final class StadiumProximityMatcher {
/// Check if coordinates are near any stadium /// Check if coordinates are near any stadium
func isNearStadium( func isNearStadium(
coordinates: CLLocationCoordinate2D, coordinates: CLLocationCoordinate2D,
radius: CLLocationDistance = StadiumProximityMatcher.searchRadius radius: CLLocationDistance = ProximityConstants.searchRadius
) -> Bool { ) -> Bool {
let matches = findNearbyStadiums(coordinates: coordinates, radius: radius) let matches = findNearbyStadiums(coordinates: coordinates, radius: radius)
return !matches.isEmpty return !matches.isEmpty

View File

@@ -21,6 +21,13 @@ final class ProgressCardGenerator {
// MARK: - Generate Card // MARK: - Generate Card
/// Generate a shareable progress card image with default options
/// - Parameter progress: The league progress data
/// - Returns: The generated UIImage
func generateCard(progress: LeagueProgress) async throws -> UIImage {
try await generateCard(progress: progress, options: ProgressCardOptions())
}
/// Generate a shareable progress card image /// Generate a shareable progress card image
/// - Parameters: /// - Parameters:
/// - progress: The league progress data /// - progress: The league progress data
@@ -28,7 +35,7 @@ final class ProgressCardGenerator {
/// - Returns: The generated UIImage /// - Returns: The generated UIImage
func generateCard( func generateCard(
progress: LeagueProgress, progress: LeagueProgress,
options: ProgressCardOptions = ProgressCardOptions() options: ProgressCardOptions
) async throws -> UIImage { ) async throws -> UIImage {
// Generate map snapshot if needed // Generate map snapshot if needed
var mapSnapshot: UIImage? var mapSnapshot: UIImage?

View File

@@ -300,7 +300,7 @@ struct PricingOptionCard: View {
private var pricePerMonth: String { private var pricePerMonth: String {
if product.id.contains("annual") { if product.id.contains("annual") {
let monthly = product.price / 12 let monthly = product.price / 12
return "\(monthly.formatted(.currency(code: product.priceFormatStyle.currencyCode ?? "USD")))/mo" return "\(monthly.formatted(.currency(code: product.priceFormatStyle.currencyCode)))/mo"
} }
return "per month" return "per month"
} }

View File

@@ -51,7 +51,8 @@ struct GamesHistoryRow: View {
case .nhl: return "hockey.puck" case .nhl: return "hockey.puck"
case .nfl: return "football" case .nfl: return "football"
case .mls: return "soccerball" case .mls: return "soccerball"
@unknown default: return "sportscourt" case .wnba: return "basketball"
case .nwsl: return "soccerball"
} }
} }
} }

View File

@@ -140,7 +140,8 @@ private struct SportChip: View {
case .nhl: return "hockey.puck" case .nhl: return "hockey.puck"
case .nfl: return "football" case .nfl: return "football"
case .mls: return "soccerball" case .mls: return "soccerball"
@unknown default: return "sportscourt" case .wnba: return "basketball"
case .nwsl: return "soccerball"
} }
} }
} }

View File

@@ -522,7 +522,7 @@ extension VisitSource {
// MARK: - Preview // MARK: - Preview
#Preview { #Preview {
let stadium = Stadium( let _ = Stadium(
id: "stadium_preview_oracle_park", id: "stadium_preview_oracle_park",
name: "Oracle Park", name: "Oracle Park",
city: "San Francisco", city: "San Francisco",

View File

@@ -324,7 +324,7 @@ enum GameDAGRouter {
} }
// Round-robin from composite buckets // Round-robin from composite buckets
var compositeKeys = Array(byComposite.keys).sorted() let compositeKeys = Array(byComposite.keys).sorted()
var indices: [String: Int] = [:] var indices: [String: Int] = [:]
while selected.count < maxCount && !compositeKeys.isEmpty { while selected.count < maxCount && !compositeKeys.isEmpty {
var addedAny = false var addedAny = false