Implements a new UI to show recommended image counts for ML training. Uses color-coded indicators (orange/green/blue) for Functional, Solid, and High-Accuracy thresholds across all 28 training categories (Foil, Stamp, and Condition models). Critical damage types (Inking, Rips, Water Damage) carry higher recommended counts to minimise false positives on NM grades. Accessible via a "?" toolbar button in Library. Bumps app version to 1.1.0. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
75 lines
2.6 KiB
Swift
75 lines
2.6 KiB
Swift
import Foundation
|
|
|
|
enum CurrencyCode: String, CaseIterable, Codable {
|
|
case usd = "USD"
|
|
case eur = "EUR"
|
|
|
|
var symbol: String {
|
|
switch self {
|
|
case .usd: return "$"
|
|
case .eur: return "€"
|
|
}
|
|
}
|
|
|
|
var scryfallKey: String {
|
|
switch self {
|
|
case .usd: return "usd"
|
|
case .eur: return "eur"
|
|
}
|
|
}
|
|
}
|
|
|
|
struct AppConfig {
|
|
// 1. CONTACT EMAIL (Required by Scryfall)
|
|
static let contactEmail = "support@iymtg.com" // Example: Use your real email
|
|
|
|
// 2. IN-APP PURCHASE ID (Use a "Consumable" type in App Store Connect for repeatable tips)
|
|
static let tipJarProductIDs: [String] = [] // Example: Use your real Product ID
|
|
|
|
// 3. VERSIONING
|
|
static let appVersion = "1.1.0" // Follows Semantic Versioning (Major.Minor.Patch)
|
|
static let buildNumber = "2" // Increments with each build submitted to App Store Connect
|
|
|
|
// Feature Flags
|
|
static let enableFoilDetection = true
|
|
static let enableConditionGrading = true
|
|
static let enableSetSymbolDetection = true
|
|
static let enableStampDetection = true
|
|
static let defaultCurrency: CurrencyCode = .usd
|
|
|
|
struct Defaults {
|
|
static let masterCollectionName = "Master Collection"
|
|
static let unsortedBoxName = "Unsorted"
|
|
static let defaultCondition = "Near Mint (NM)"
|
|
static let defaultFoil = "None"
|
|
}
|
|
|
|
static var isTrainingOptIn: Bool {
|
|
get { UserDefaults.standard.bool(forKey: "TrainingOptIn") }
|
|
set { UserDefaults.standard.set(newValue, forKey: "TrainingOptIn") }
|
|
}
|
|
|
|
// Firebase secondary backup — metadata only (no card images).
|
|
// Default: false. Users opt-in via the Cloud Backup section in Library settings.
|
|
static var isFirebaseBackupEnabled: Bool {
|
|
get { UserDefaults.standard.bool(forKey: "FirebaseBackupEnabled") }
|
|
set { UserDefaults.standard.set(newValue, forKey: "FirebaseBackupEnabled") }
|
|
}
|
|
|
|
static var scryfallUserAgent: String {
|
|
return "IYmtg/\(appVersion) (\(contactEmail))"
|
|
}
|
|
|
|
static func validate() {
|
|
#if DEBUG
|
|
if contactEmail.contains("yourdomain.com") {
|
|
fatalError("🛑 SETUP ERROR: Change 'contactEmail' in AppConfig.swift to your real email.")
|
|
}
|
|
if tipJarProductIDs.isEmpty {
|
|
print("⚠️ CONFIG WARNING: 'tipJarProductIDs' is empty. Tip Jar will not be available.")
|
|
} else if let first = tipJarProductIDs.first, (first.contains("yourname") || first == "com.iymtg.app.tip") {
|
|
print("⚠️ CONFIG WARNING: 'tipJarProductIDs' contains placeholder. IAP will not load.")
|
|
}
|
|
#endif
|
|
}
|
|
} |