From 420a6ea01490862bf4fa19d43bd7315f14a805a8 Mon Sep 17 00:00:00 2001 From: Stefan Lange-Hegermann Date: Mon, 20 Oct 2025 15:35:29 +0200 Subject: [PATCH] better presentation fot the App Store --- Cable.xcodeproj/project.pbxproj | 20 +- Cable/AppIcon copy.icon/Assets/body 3.png | Bin 0 -> 9123 bytes Cable/AppIcon copy.icon/Assets/fuse-top.png | Bin 0 -> 3645 bytes Cable/AppIcon copy.icon/Assets/legs 2.png | Bin 0 -> 15079 bytes Cable/AppIcon copy.icon/icon.json | 295 +++++++++++++++ Cable/AppIcon.icon/Assets/body 3.png | Bin 0 -> 9123 bytes Cable/AppIcon.icon/Assets/box-2.png | Bin 72264 -> 0 bytes Cable/AppIcon.icon/Assets/flash.png | Bin 0 -> 3738 bytes Cable/AppIcon.icon/Assets/fuse-top.png | Bin 0 -> 3645 bytes Cable/AppIcon.icon/Assets/legs 2.png | Bin 0 -> 15079 bytes Cable/AppIcon.icon/Assets/voltplan-lines.png | Bin 11028 -> 0 bytes .../AppIcon.icon/Assets/voltplan-logo 2 2.png | Bin 23221 -> 0 bytes Cable/AppIcon.icon/icon.json | 190 +++++++--- Cable/Base.lproj/Localizable.strings | 24 ++ Cable/ComponentLibraryView.swift | 218 ++++++++++- Cable/LoadsView.swift | 3 +- Cable/SystemsView.swift | 85 +++-- Cable/de.lproj/Localizable.strings | 28 +- Cable/es.lproj/Localizable.strings | 24 ++ Cable/fr.lproj/Localizable.strings | 24 ++ Cable/nl.lproj/Localizable.strings | 24 ++ CableTests/ComponentLibraryItemTests.swift | 104 ++++++ .../CableUITestsScreenshot.swift | 88 ++++- frame_screens.sh | 343 ++++++++++++------ shooter.sh | 120 +++--- 25 files changed, 1332 insertions(+), 258 deletions(-) create mode 100644 Cable/AppIcon copy.icon/Assets/body 3.png create mode 100644 Cable/AppIcon copy.icon/Assets/fuse-top.png create mode 100644 Cable/AppIcon copy.icon/Assets/legs 2.png create mode 100644 Cable/AppIcon copy.icon/icon.json create mode 100644 Cable/AppIcon.icon/Assets/body 3.png delete mode 100644 Cable/AppIcon.icon/Assets/box-2.png create mode 100644 Cable/AppIcon.icon/Assets/flash.png create mode 100644 Cable/AppIcon.icon/Assets/fuse-top.png create mode 100644 Cable/AppIcon.icon/Assets/legs 2.png delete mode 100644 Cable/AppIcon.icon/Assets/voltplan-lines.png delete mode 100644 Cable/AppIcon.icon/Assets/voltplan-logo 2 2.png create mode 100644 CableTests/ComponentLibraryItemTests.swift diff --git a/Cable.xcodeproj/project.pbxproj b/Cable.xcodeproj/project.pbxproj index 539ecb2..b840e20 100644 --- a/Cable.xcodeproj/project.pbxproj +++ b/Cable.xcodeproj/project.pbxproj @@ -403,9 +403,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Cable/Cable.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; - DEVELOPMENT_TEAM = RE4FXQ754N; + CURRENT_PROJECT_VERSION = 14; + DEVELOPMENT_TEAM = ""; ENABLE_APP_SANDBOX = YES; ENABLE_PREVIEWS = YES; ENABLE_USER_SELECTED_FILES = readonly; @@ -421,9 +422,10 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 0.21; + MARKETING_VERSION = 1.1; PRODUCT_BUNDLE_IDENTIFIER = app.voltplan.CableApp; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -436,9 +438,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Cable/Cable.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; - DEVELOPMENT_TEAM = RE4FXQ754N; + CURRENT_PROJECT_VERSION = 14; + DEVELOPMENT_TEAM = ""; ENABLE_APP_SANDBOX = YES; ENABLE_PREVIEWS = YES; ENABLE_USER_SELECTED_FILES = readonly; @@ -454,9 +457,10 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 0.21; + MARKETING_VERSION = 1.1; PRODUCT_BUNDLE_IDENTIFIER = app.voltplan.CableApp; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -516,7 +520,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 18.5; + IPHONEOS_DEPLOYMENT_TARGET = 17.6; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -575,7 +579,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 18.5; + IPHONEOS_DEPLOYMENT_TARGET = 17.6; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; diff --git a/Cable/AppIcon copy.icon/Assets/body 3.png b/Cable/AppIcon copy.icon/Assets/body 3.png new file mode 100644 index 0000000000000000000000000000000000000000..965b1ca7ef44690521dff8a492e8660f6e70e2b5 GIT binary patch literal 9123 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 m_wUp{MSr)>xL_e+%k literal 0 HcmV?d00001 diff --git a/Cable/AppIcon copy.icon/Assets/legs 2.png b/Cable/AppIcon copy.icon/Assets/legs 2.png new file mode 100644 index 0000000000000000000000000000000000000000..d0f41a6b8474fbf53f21c4cf83ed37794f0ed69d GIT binary patch literal 15079 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%0D`9; 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

Il8NP-u#^1v!9_9kA2Pj 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 literal 0 HcmV?d00001 diff --git a/Cable/AppIcon.icon/Assets/fuse-top.png b/Cable/AppIcon.icon/Assets/fuse-top.png new file mode 100644 index 0000000000000000000000000000000000000000..780bf2cbad379dac58ae06b28c81944d02df2045 GIT binary patch literal 3645 zcmeAS@N?(olHy`uVBq!ia0y~yV0s5+ujXI_l9u9Y@ee$7ty^K!dfN@9|%r>l5AxazE$5gr)%Vv8!%{pIi0n>HESR2gK+-?$!^R(C$X?Agrgzdsr9?3X;<{^$3x zneXS{lb!SDQ(n*I->H^g73E)PGO=(7C^$4QFfy^&H66%{)O-JY&zAjVPs8=&Y93u; zukD&R&!YUkas1u4#~v5=>Gy6t((n1--wmt*tn+}o@QmV_$!G4r`TqIkbA6j{mmkl6 zdP2j#`aZv1ZBqHGr=~SOey~^hAnEw;o}hPHf89I%`nP{t-~ao2EWDItBZf|!K3J)hqHeDHI>&9`^Ic7Hfs^r-LSl#6vTCzD}DGBRzCN|;lbzj}T4 z-#atq?`^iOeB}RnH~aQo)7JYVIkm8{GPnNetLNp9j~u+-`|YuXoG{#?3_%I@+iCIj zp=ma^f;{;VMzc&hP*L*tw%23smzt7rUobMsGTlzQzgGWCUAnuhE83>avLl@2(IsxU>4)LLRt1jXDWC(#16qd@aVq zdtb?%f<-fjz^DsXu@yHc@g!m{#`#bOG^-L_>NlEYrSWmzyAFSe>Ug+oqbyS ziV-fhWx8#4-|W}6tJ}lg|7Tn#UiW|Q_3y?15Bw6EC|>m{3t{7fZ^Adser`Lvy|?c1 z?*BJ>%eQS`zyI&%a=V}X?DKd34wkRau3dYgdV1=e($AmosY7}npdffquW9gq&%T^9 zlk@j|d}khC`Mdi6o}b#iv*l&#|KAaxzqfw-nf7NA%a6zS$=2UPYRt3zvu?DUb~^c- m_wUp{MSr)>xL_e+%k literal 0 HcmV?d00001 diff --git a/Cable/AppIcon.icon/Assets/legs 2.png b/Cable/AppIcon.icon/Assets/legs 2.png new file mode 100644 index 0000000000000000000000000000000000000000..d0f41a6b8474fbf53f21c4cf83ed37794f0ed69d GIT binary patch literal 15079 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%0D`9; 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 QtCUFVslHmJip{(K0X0A?zW@LL diff --git a/Cable/AppIcon.icon/Assets/voltplan-logo 2 2.png b/Cable/AppIcon.icon/Assets/voltplan-logo 2 2.png deleted file mode 100644 index 6dd9922e577a2e869f1616545a23c64c1e8b8020..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23221 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 diff --git a/Cable/AppIcon.icon/icon.json b/Cable/AppIcon.icon/icon.json index 33fc7f6..a57622e 100644 --- a/Cable/AppIcon.icon/icon.json +++ b/Cable/AppIcon.icon/icon.json @@ -1,63 +1,171 @@ { "fill" : { - "automatic-gradient" : "display-p3:0.50588,0.79216,0.56471,1.00000" + "linear-gradient" : [ + "display-p3:0.92941,1.00000,0.92941,1.00000", + "extended-gray:1.00000,1.00000" + ] }, "groups" : [ { + "blur-material" : 0.9, "layers" : [ - { - "blend-mode" : "normal", - "glass" : false, - "hidden" : false, - "image-name" : "voltplan-lines.png", - "name" : "voltplan-lines", - "position" : { - "scale" : 1, - "translation-in-points" : [ - 0, - 80.8265625 - ] - } - }, { "fill" : { - "linear-gradient" : [ - "srgb:1.00000,1.00000,1.00000,1.00000", - "srgb:1.00000,1.00000,1.00000,0.63382" - ] + "solid" : "srgb:1.00000,0.57811,0.00000,1.00000" }, - "image-name" : "voltplan-logo 2 2.png", - "name" : "voltplan-logo 2 2", + "glass" : true, + "hidden" : true, + "image-name" : "flash.png", + "name" : "flash", + "opacity" : 1, "position" : { - "scale" : 1, + "scale" : 0.8, "translation-in-points" : [ - -3, - 77.55625 - ] - } - }, - { - "fill" : { - "linear-gradient" : [ - "srgb:1.00000,1.00000,1.00000,1.00000", - "srgb:1.00000,1.00000,1.00000,0.50000" - ] - }, - "image-name" : "box-2.png", - "name" : "Layer", - "position" : { - "scale" : 1, - "translation-in-points" : [ - 0, - -91.0703125 + 7.4921875, + -218.84375 ] } } ], + "shadow" : { + "kind" : "layer-color", + "opacity" : 0.5 + }, + "specular" : false, + "translucency" : { + "enabled" : false, + "value" : 0.5 + } + }, + { + "blur-material" : null, + "layers" : [ + { + "fill-specializations" : [ + { + "value" : { + "solid" : "display-p3:0.31812,0.56494,0.59766,1.00000" + } + }, + { + "appearance" : "tinted", + "value" : { + "solid" : "srgb:1.00000,1.00000,1.00000,1.00000" + } + } + ], + "image-name" : "fuse-top.png", + "name" : "fuse-top", + "opacity" : 1, + "position" : { + "scale" : 0.9, + "translation-in-points" : [ + 0, + -225.390625 + ] + } + }, + { + "fill-specializations" : [ + { + "value" : { + "automatic-gradient" : "display-p3:0.31812,0.56494,0.59766,1.00000" + } + }, + { + "appearance" : "tinted", + "value" : { + "automatic-gradient" : "srgb:0.83742,0.83744,0.83743,1.00000" + } + } + ], + "glass" : true, + "hidden" : false, + "image-name" : "body 3.png", + "name" : "body 3", + "opacity-specializations" : [ + { + "value" : 1 + }, + { + "appearance" : "tinted", + "value" : 1 + } + ], + "position" : { + "scale" : 0.9, + "translation-in-points" : [ + 0, + -74.9921875 + ] + } + } + ], + "lighting" : "individual", + "name" : "Group", + "opacity" : 0.8, "shadow" : { "kind" : "neutral", "opacity" : 0.5 }, + "specular" : true, + "translucency" : { + "enabled" : false, + "value" : 0.8 + } + }, + { + "hidden" : false, + "layers" : [ + { + "fill-specializations" : [ + { + "value" : { + "automatic-gradient" : "srgb:0.37056,0.37056,0.37056,1.00000" + } + }, + { + "appearance" : "dark", + "value" : { + "automatic-gradient" : "srgb:0.75407,0.75409,0.75408,1.00000" + } + }, + { + "appearance" : "tinted", + "value" : { + "automatic-gradient" : "srgb:0.75407,0.75409,0.75408,1.00000" + } + } + ], + "glass-specializations" : [ + { + "appearance" : "tinted", + "value" : true + } + ], + "image-name" : "legs 2.png", + "name" : "legs 2", + "opacity-specializations" : [ + { + "appearance" : "tinted", + "value" : 1 + } + ], + "position" : { + "scale" : 0.9, + "translation-in-points" : [ + 0, + 100 + ] + } + } + ], + "lighting" : "combined", + "shadow" : { + "kind" : "layer-color", + "opacity" : 0.5 + }, + "specular" : false, "translucency" : { "enabled" : true, "value" : 0.5 diff --git a/Cable/Base.lproj/Localizable.strings b/Cable/Base.lproj/Localizable.strings index 3bd65ff..99e266c 100644 --- a/Cable/Base.lproj/Localizable.strings +++ b/Cable/Base.lproj/Localizable.strings @@ -43,3 +43,27 @@ "sample.load.lighting.name" = "LED strip lighting"; "sample.load.compressor.name" = "Air compressor"; "sample.load.charger.name" = "Tool charger"; +"system.icon.keywords.rv" = "rv, van, camper, motorhome, coach"; +"system.icon.keywords.truck" = "truck, trailer, rig"; +"system.icon.keywords.boat" = "boat, marine, yacht, sail"; +"system.icon.keywords.plane" = "plane, air, flight"; +"system.icon.keywords.ferry" = "ferry, ship"; +"system.icon.keywords.house" = "house, home, cabin, cottage, lodge"; +"system.icon.keywords.building" = "building, office, warehouse, factory, facility"; +"system.icon.keywords.tent" = "camp, tent, outdoor"; +"system.icon.keywords.solar" = "solar, sun"; +"system.icon.keywords.battery" = "battery, storage"; +"system.icon.keywords.server" = "server, data, network, rack"; +"system.icon.keywords.computer" = "computer, electronics, lab, tech"; +"system.icon.keywords.gear" = "gear, mechanic, machine, workshop"; +"system.icon.keywords.tool" = "tool, maintenance, repair, shop"; +"system.icon.keywords.hammer" = "hammer, carpentry"; +"system.icon.keywords.light" = "light, lighting, lamp"; +"system.icon.keywords.bolt" = "bolt, power, electric"; +"system.icon.keywords.plug" = "plug"; +"system.icon.keywords.engine" = "engine, generator, motor"; +"system.icon.keywords.fuel" = "fuel, diesel, gas"; +"system.icon.keywords.water" = "water, pump, tank"; +"system.icon.keywords.heat" = "heat, heater, furnace"; +"system.icon.keywords.cold" = "cold, freeze, cool"; +"system.icon.keywords.climate" = "climate, hvac, temperature"; diff --git a/Cable/ComponentLibraryView.swift b/Cable/ComponentLibraryView.swift index 6463ad0..c5e25c6 100644 --- a/Cable/ComponentLibraryView.swift +++ b/Cable/ComponentLibraryView.swift @@ -9,6 +9,7 @@ struct ComponentLibraryItem: Identifiable, Equatable { let id: String let name: String + let translations: [String: String] let voltageIn: Double? let voltageOut: Double? let watt: Double? @@ -39,10 +40,24 @@ struct ComponentLibraryItem: Identifiable, Equatable { return String(format: "%.1fA", current) } + var localizedName: String { + localizedName(usingPreferredLanguages: Locale.preferredLanguages) ?? name + } + + func localizedName(usingPreferredLanguages languages: [String]) -> String? { + guard let primaryIdentifier = languages.first else { return nil } + let locale = Locale(identifier: primaryIdentifier) + return translation(for: locale) + } + var primaryAffiliateLink: AffiliateLink? { affiliateLink(matching: Locale.current.region?.identifier) } + func localizedName(for locale: Locale) -> String { + translation(for: locale) ?? name + } + func affiliateLink(matching regionCode: String?) -> AffiliateLink? { guard !affiliateLinks.isEmpty else { return nil } @@ -64,6 +79,108 @@ struct ComponentLibraryItem: Identifiable, Equatable { return affiliateLinks.first } + + private func translation(for locale: Locale) -> String? { + guard !translations.isEmpty else { return nil } + + let lookupKeys = ComponentLibraryItem.lookupKeys(for: locale) + + for key in lookupKeys { + if let match = translations[key] { + return match + } + } + + let normalizedTranslations = translations.reduce(into: [String: String]()) { result, element in + let normalizedKey = ComponentLibraryItem.normalizeLocaleKey(element.key) + result[normalizedKey] = element.value + + if let languageOnlyKey = ComponentLibraryItem.languageComponent(fromNormalizedKey: normalizedKey), + result[languageOnlyKey] == nil { + result[languageOnlyKey] = element.value + } + } + + for key in lookupKeys { + let normalizedKey = ComponentLibraryItem.normalizeLocaleKey(key) + if let match = normalizedTranslations[normalizedKey] { + return match + } + } + + return nil + } + + private static func lookupKeys(for locale: Locale) -> [String] { + var keys: [String] = [] + + func append(_ value: String?) { + guard let value, !value.isEmpty else { return } + + for variant in variants(for: value) { + if !keys.contains(variant) { + keys.append(variant) + } + } + } + + append(locale.identifier) + + let components = Locale.components(fromIdentifier: locale.identifier) + + if let language = components[NSLocale.Key.languageCode.rawValue]?.lowercased() { + if let region = components[NSLocale.Key.countryCode.rawValue]?.uppercased() { + append("\(language)_\(region)") + } + append(language) + } + + if let languageCode = locale.language.languageCode?.identifier.lowercased() { + append(languageCode) + } + + if let regionIdentifier = locale.region?.identifier.uppercased(), + let languageIdentifier = locale.language.languageCode?.identifier.lowercased() { + append("\(languageIdentifier)_\(regionIdentifier)") + } + + return keys + } + + private static func normalizeLocaleKey(_ key: String) -> String { + let sanitized = key.replacingOccurrences(of: "-", with: "_") + let parts = sanitized.split(separator: "_", omittingEmptySubsequences: true) + + guard let languagePart = parts.first else { + return sanitized.lowercased() + } + + let language = languagePart.lowercased() + + if parts.count >= 2, let regionPart = parts.last { + return "\(language)_\(regionPart.uppercased())" + } + + return language + } + + private static func languageComponent(fromNormalizedKey key: String) -> String? { + let components = key.split(separator: "_", omittingEmptySubsequences: true) + guard let language = components.first else { return nil } + return String(language) + } + + private static func variants(for key: String) -> [String] { + var collected: [String] = [] + let underscore = key.replacingOccurrences(of: "-", with: "_") + let hyphen = key.replacingOccurrences(of: "_", with: "-") + + for candidate in Set([key, underscore, hyphen]) { + collected.append(candidate) + } + + return collected + } } @MainActor @@ -113,7 +230,7 @@ final class ComponentLibraryViewModel: ObservableObject { components?.queryItems = [ URLQueryItem(name: "filter", value: "(type='load')"), URLQueryItem(name: "sort", value: "+name"), - URLQueryItem(name: "fields", value: "id,collectionId,name,icon,voltage_in,voltage_out,watt"), + URLQueryItem(name: "fields", value: "id,collectionId,name,translations,icon,voltage_in,voltage_out,watt"), URLQueryItem(name: "page", value: "\(page)"), URLQueryItem(name: "perPage", value: "\(perPage)") ] @@ -153,6 +270,7 @@ final class ComponentLibraryViewModel: ObservableObject { ComponentLibraryItem( id: record.id, name: record.name, + translations: record.translations?.flattened ?? [:], voltageIn: record.voltageIn, voltageOut: record.voltageOut, watt: record.watt, @@ -300,6 +418,7 @@ final class ComponentLibraryViewModel: ObservableObject { let id: String let collectionId: String let name: String + let translations: TranslationsContainer? let icon: String? let voltageIn: Double? let voltageOut: Double? @@ -309,11 +428,64 @@ final class ComponentLibraryViewModel: ObservableObject { case id case collectionId case name + case translations case icon case voltageIn = "voltage_in" case voltageOut = "voltage_out" case watt } + + struct TranslationsContainer: Decodable { + private let storage: [String: TranslationValue] + + init(from decoder: Decoder) throws { + let container = try decoder.singleValueContainer() + storage = try container.decode([String: TranslationValue].self) + } + + var flattened: [String: String] { + storage.reduce(into: [:]) { result, entry in + if let value = entry.value.flattened { + result[entry.key] = value + } + } + } + } + + private enum TranslationValue: Decodable { + case string(String) + case dictionary([String: String]) + + init(from decoder: Decoder) throws { + let singleValue = try decoder.singleValueContainer() + if let string = try? singleValue.decode(String.self) { + self = .string(string) + return + } + + if let dictionary = try? singleValue.decode([String: String].self) { + self = .dictionary(dictionary) + return + } + + self = .dictionary([:]) + } + + var flattened: String? { + switch self { + case .string(let value): + return value.isEmpty ? nil : value + case .dictionary(let dictionary): + if let name = dictionary["name"], !name.isEmpty { + return name + } + if let value = dictionary["value"], !value.isEmpty { + return value + } + return dictionary.values.first(where: { !$0.isEmpty }) + } + } + } } private struct AffiliateLinksResponse: Decodable { @@ -396,14 +568,17 @@ struct ComponentLibraryView: View { .padding() .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) } else { - List(filteredItems) { item in - Button { - onSelect(item) - dismiss() - } label: { - ComponentRow(item: item) + List { + ForEach(filteredItems) { item in + Button { + onSelect(item) + dismiss() + } label: { + ComponentRow(item: item) + } + .buttonStyle(.plain) } - .buttonStyle(.plain) + poweredByVoltplanRow } .listStyle(.insetGrouped) } @@ -414,7 +589,30 @@ struct ComponentLibraryView: View { guard !trimmedQuery.isEmpty else { return viewModel.items } return viewModel.items.filter { item in - item.name.localizedCaseInsensitiveContains(trimmedQuery) + let localizedName = item.localizedName + return localizedName.localizedCaseInsensitiveContains(trimmedQuery) + || item.name.localizedCaseInsensitiveContains(trimmedQuery) + } + } + + @ViewBuilder + private var poweredByVoltplanRow: some View { + if let url = URL(string: "https://voltplan.app") { + Section { + Link(destination: url) { + Image("PoweredByVoltplan") + .renderingMode(.original) + .resizable() + .scaledToFit() + .frame(maxWidth: 220) + .padding(.vertical, 20) + .frame(maxWidth: .infinity) + .accessibilityLabel("Powered by Voltplan") + } + .listRowBackground(Color.clear) + .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)) + } + .textCase(nil) } } } @@ -426,7 +624,7 @@ private struct ComponentRow: View { HStack(spacing: 12) { iconView VStack(alignment: .leading, spacing: 4) { - Text(item.name) + Text(item.localizedName) .font(.headline) .foregroundColor(.primary) detailLine diff --git a/Cable/LoadsView.swift b/Cable/LoadsView.swift index 4945a7f..d22e609 100644 --- a/Cable/LoadsView.swift +++ b/Cable/LoadsView.swift @@ -292,7 +292,8 @@ struct LoadsView: View { } private func addComponent(_ item: ComponentLibraryItem) { - let baseName = item.name.isEmpty ? "Library Load" : item.name + let localizedName = item.localizedName + let baseName = localizedName.isEmpty ? "Library Load" : localizedName let loadName = uniqueLoadName(startingWith: baseName) let voltage = item.displayVoltage ?? 12.0 let power = item.watt ?? (item.current != nil ? item.current! * voltage : 0) diff --git a/Cable/SystemsView.swift b/Cable/SystemsView.swift index e00db4b..5fd80e6 100644 --- a/Cable/SystemsView.swift +++ b/Cable/SystemsView.swift @@ -23,32 +23,34 @@ struct SystemsView: View { "pink", "teal", "indigo", "mint", "cyan", "brown", "gray" ] private let defaultSystemIconName = "building.2" - private let systemIconMappings: [(keywords: [String], icon: String)] = [ - (["rv", "van", "camper", "motorhome", "coach"], "bus"), - (["truck", "trailer", "rig"], "truck.box"), - (["boat", "marine", "yacht", "sail"], "sailboat"), - (["plane", "air", "flight"], "airplane"), - (["ferry", "ship"], "ferry"), - (["house", "home", "cabin", "cottage", "lodge"], "house"), - (["building", "office", "warehouse", "factory", "facility"], "building"), - (["camp", "tent", "outdoor"], "tent"), - (["solar", "sun"], "sun.max"), - (["battery", "storage"], "battery.100"), - (["server", "data", "network", "rack"], "server.rack"), - (["computer", "electronics", "lab", "tech"], "cpu"), - (["gear", "mechanic", "machine", "workshop"], "gear"), - (["tool", "maintenance", "repair", "shop"], "wrench.adjustable"), - (["hammer", "carpentry"], "hammer"), - (["light", "lighting", "lamp"], "lightbulb"), - (["bolt", "power", "electric"], "bolt"), - (["plug"], "powerplug"), - (["engine", "generator", "motor"], "engine.combustion"), - (["fuel", "diesel", "gas"], "fuelpump"), - (["water", "pump", "tank"], "drop"), - (["heat", "heater", "furnace"], "flame"), - (["cold", "freeze", "cool"], "snowflake"), - (["climate", "hvac", "temperature"], "thermometer") - ] + private var systemIconMappings: [(keywords: [String], icon: String)] { + [ + (keywords(for: "system.icon.keywords.rv", fallback: ["rv", "van", "camper", "motorhome", "coach"]), "bus"), + (keywords(for: "system.icon.keywords.truck", fallback: ["truck", "trailer", "rig"]), "truck.box"), + (keywords(for: "system.icon.keywords.boat", fallback: ["boat", "marine", "yacht", "sail"]), "sailboat"), + (keywords(for: "system.icon.keywords.plane", fallback: ["plane", "air", "flight"]), "airplane"), + (keywords(for: "system.icon.keywords.ferry", fallback: ["ferry", "ship"]), "ferry"), + (keywords(for: "system.icon.keywords.house", fallback: ["house", "home", "cabin", "cottage", "lodge"]), "house"), + (keywords(for: "system.icon.keywords.building", fallback: ["building", "office", "warehouse", "factory", "facility"]), "building"), + (keywords(for: "system.icon.keywords.tent", fallback: ["camp", "tent", "outdoor"]), "tent"), + (keywords(for: "system.icon.keywords.solar", fallback: ["solar", "sun"]), "sun.max"), + (keywords(for: "system.icon.keywords.battery", fallback: ["battery", "storage"]), "battery.100"), + (keywords(for: "system.icon.keywords.server", fallback: ["server", "data", "network", "rack"]), "server.rack"), + (keywords(for: "system.icon.keywords.computer", fallback: ["computer", "electronics", "lab", "tech"]), "cpu"), + (keywords(for: "system.icon.keywords.gear", fallback: ["gear", "mechanic", "machine", "workshop"]), "gear"), + (keywords(for: "system.icon.keywords.tool", fallback: ["tool", "maintenance", "repair", "shop"]), "wrench.adjustable"), + (keywords(for: "system.icon.keywords.hammer", fallback: ["hammer", "carpentry"]), "hammer"), + (keywords(for: "system.icon.keywords.light", fallback: ["light", "lighting", "lamp"]), "lightbulb"), + (keywords(for: "system.icon.keywords.bolt", fallback: ["bolt", "power", "electric"]), "bolt"), + (keywords(for: "system.icon.keywords.plug", fallback: ["plug"]), "powerplug"), + (keywords(for: "system.icon.keywords.engine", fallback: ["engine", "generator", "motor"]), "engine.combustion"), + (keywords(for: "system.icon.keywords.fuel", fallback: ["fuel", "diesel", "gas"]), "fuelpump"), + (keywords(for: "system.icon.keywords.water", fallback: ["water", "pump", "tank"]), "drop"), + (keywords(for: "system.icon.keywords.heat", fallback: ["heat", "heater", "furnace"]), "flame"), + (keywords(for: "system.icon.keywords.cold", fallback: ["cold", "freeze", "cool"]), "snowflake"), + (keywords(for: "system.icon.keywords.climate", fallback: ["climate", "hvac", "temperature"]), "thermometer") + ] + } private struct SystemNavigationTarget: Identifiable, Hashable { let id = UUID() @@ -224,7 +226,10 @@ struct SystemsView: View { } private func createLoad(from item: ComponentLibraryItem, in system: ElectricalSystem) -> SavedLoad { - let baseName = item.name.isEmpty ? String(localized: "default.load.library", comment: "Default name when importing a library load") : item.name + let localizedName = item.localizedName + let baseName = localizedName.isEmpty + ? String(localized: "default.load.library", comment: "Default name when importing a library load") + : localizedName let loadName = uniqueLoadName(for: system, startingWith: baseName) let voltage = item.displayVoltage ?? 12.0 @@ -352,6 +357,32 @@ struct SystemsView: View { return defaultSystemIconName } + private func keywords(for localizationKey: String, fallback: [String]) -> [String] { + let fallbackValue = fallback.joined(separator: ",") + let localizedKeywords = NSLocalizedString( + localizationKey, + tableName: nil, + bundle: .main, + value: fallbackValue, + comment: "" + ) + let separators = CharacterSet(charactersIn: ",;") + let components = localizedKeywords + .components(separatedBy: separators) + .map { $0.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() } + .filter { !$0.isEmpty } + + var uniqueKeywords: [String] = [] + + for keyword in fallback.map({ $0.lowercased() }) + components { + if !uniqueKeywords.contains(keyword) { + uniqueKeywords.append(keyword) + } + } + + return uniqueKeywords + } + private func colorForName(_ colorName: String) -> Color { switch colorName { case "blue": return .blue diff --git a/Cable/de.lproj/Localizable.strings b/Cable/de.lproj/Localizable.strings index 921adbb..08328d0 100644 --- a/Cable/de.lproj/Localizable.strings +++ b/Cable/de.lproj/Localizable.strings @@ -44,6 +44,30 @@ "sample.load.lighting.name" = "LED-Streifenbeleuchtung"; "sample.load.compressor.name" = "Luftkompressor"; "sample.load.charger.name" = "Werkzeugladegerät"; +"system.icon.keywords.rv" = "wohnmobil, camper, campervan, van, reisemobil, campingbus"; +"system.icon.keywords.truck" = "lkw, anhänger, zugmaschine, trailer"; +"system.icon.keywords.boat" = "boot, schiff, yacht, segel, segelboot"; +"system.icon.keywords.plane" = "flugzeug, flug, flieger, luft"; +"system.icon.keywords.ferry" = "fähre, schiff"; +"system.icon.keywords.house" = "haus, zuhause, hütte, ferienhaus, lodge"; +"system.icon.keywords.building" = "gebäude, büro, lagerhalle, fabrik, anlage"; +"system.icon.keywords.tent" = "camp, camping, zelt, outdoor"; +"system.icon.keywords.solar" = "solar, sonne, pv"; +"system.icon.keywords.battery" = "batterie, speicher, akku"; +"system.icon.keywords.server" = "server, daten, netzwerk, rack, rechenzentrum"; +"system.icon.keywords.computer" = "computer, elektronik, labor, technik"; +"system.icon.keywords.gear" = "getriebe, mechanik, maschine, werkstatt"; +"system.icon.keywords.tool" = "werkzeug, wartung, reparatur, werkstatt"; +"system.icon.keywords.hammer" = "hammer, tischlerei, zimmerei"; +"system.icon.keywords.light" = "licht, beleuchtung, lampe"; +"system.icon.keywords.bolt" = "strom, power, elektrisch, spannung"; +"system.icon.keywords.plug" = "stecker, netzstecker"; +"system.icon.keywords.engine" = "motor, generator, antrieb"; +"system.icon.keywords.fuel" = "kraftstoff, diesel, benzin"; +"system.icon.keywords.water" = "wasser, pumpe, tank"; +"system.icon.keywords.heat" = "heizung, heizer, ofen"; +"system.icon.keywords.cold" = "kalt, kühlen, eis, gefrieren"; +"system.icon.keywords.climate" = "klima, hvac, temperatur"; // Direct strings "Systems" = "Systeme"; @@ -52,9 +76,9 @@ "System Name" = "Systemname"; "Create System" = "System erstellen"; "Create your first system" = "Erstelle dein erstes System"; -"Give your setup a name so **Cable by VoltPlan** can organize loads, wiring, and recommendations in one place." = "Gib deinem System einen Namen, damit **Cable by VoltPlan** alle zusammengehörenden Verbraucher gruppieren kann."; +"Give your setup a name so **Cable by VoltPlan** can organize loads, wiring, and recommendations in one place." = "Ob \"**Mein System**\", \"**Motoryacht LARGO**\" oder \"**Camper Luigi**\". Dein System braucht einen Namen."; "Add your first component" = "Erstelle deine erste Komponente"; -"Bring your system to life with components and let **Cable by VoltPlan** handle cable and fuse recommendations." = "Erwecke dein System mit Komponenten zum Leben und überlasse **Cable by VoltPlan** die Kabel- und Sicherungsempfehlungen."; +"Bring your system to life with components and let **Cable by VoltPlan** handle cable and fuse recommendations." = "Komponenten sind das Herz von Cable. Stelle sicher, dass du nie wieder ein zu dünnes Kabel oder die falsche Sicherung verwendest."; "Create Component" = "Komponente erstellen"; "Browse Library" = "Bibliothek durchsuchen"; "Browse" = "Durchsuchen"; diff --git a/Cable/es.lproj/Localizable.strings b/Cable/es.lproj/Localizable.strings index fbe9ea4..aafda08 100644 --- a/Cable/es.lproj/Localizable.strings +++ b/Cable/es.lproj/Localizable.strings @@ -44,6 +44,30 @@ "sample.load.lighting.name" = "Iluminación LED"; "sample.load.compressor.name" = "Compresor de aire"; "sample.load.charger.name" = "Cargador de herramientas"; +"system.icon.keywords.rv" = "autocaravana, camper, caravana, furgo, van"; +"system.icon.keywords.truck" = "camión, remolque, tráiler"; +"system.icon.keywords.boat" = "barco, embarcación, yate, vela"; +"system.icon.keywords.plane" = "avión, vuelo, aire"; +"system.icon.keywords.ferry" = "ferry, transbordador, barco"; +"system.icon.keywords.house" = "casa, hogar, cabaña, chalet"; +"system.icon.keywords.building" = "edificio, oficina, almacén, fábrica, instalación"; +"system.icon.keywords.tent" = "camping, tienda, exterior"; +"system.icon.keywords.solar" = "solar, sol, fotovoltaico"; +"system.icon.keywords.battery" = "batería, almacenamiento, acumulador"; +"system.icon.keywords.server" = "servidor, datos, red, rack"; +"system.icon.keywords.computer" = "computadora, ordenador, electrónica, laboratorio, tecnología"; +"system.icon.keywords.gear" = "engranaje, mecánica, máquina, taller"; +"system.icon.keywords.tool" = "herramienta, mantenimiento, reparación, taller"; +"system.icon.keywords.hammer" = "martillo, carpintería"; +"system.icon.keywords.light" = "luz, iluminación, lámpara"; +"system.icon.keywords.bolt" = "volt, energía, eléctrico, potencia"; +"system.icon.keywords.plug" = "enchufe, clavija"; +"system.icon.keywords.engine" = "motor, generador"; +"system.icon.keywords.fuel" = "combustible, diésel, gasolina"; +"system.icon.keywords.water" = "agua, bomba, tanque, depósito"; +"system.icon.keywords.heat" = "calor, calefacción, horno"; +"system.icon.keywords.cold" = "frío, congelar, enfriar"; +"system.icon.keywords.climate" = "clima, hvac, temperatura"; // Direct strings "Systems" = "Sistemas"; diff --git a/Cable/fr.lproj/Localizable.strings b/Cable/fr.lproj/Localizable.strings index 82b5e91..1ab2cd2 100644 --- a/Cable/fr.lproj/Localizable.strings +++ b/Cable/fr.lproj/Localizable.strings @@ -44,6 +44,30 @@ "sample.load.lighting.name" = "Éclairage LED"; "sample.load.compressor.name" = "Compresseur d'air"; "sample.load.charger.name" = "Chargeur d'outils"; +"system.icon.keywords.rv" = "camping-car, van, fourgon, caravane, motorhome"; +"system.icon.keywords.truck" = "camion, remorque, poids lourd"; +"system.icon.keywords.boat" = "bateau, marine, yacht, voile"; +"system.icon.keywords.plane" = "avion, vol, air"; +"system.icon.keywords.ferry" = "ferry, traversier, bateau"; +"system.icon.keywords.house" = "maison, foyer, cabane, chalet, lodge"; +"system.icon.keywords.building" = "bâtiment, bureau, entrepôt, usine, installation"; +"system.icon.keywords.tent" = "camping, tente, plein air"; +"system.icon.keywords.solar" = "solaire, soleil"; +"system.icon.keywords.battery" = "batterie, stockage, accumulateur"; +"system.icon.keywords.server" = "serveur, données, réseau, rack"; +"system.icon.keywords.computer" = "ordinateur, électronique, labo, techno"; +"system.icon.keywords.gear" = "engrenage, mécanique, machine, atelier"; +"system.icon.keywords.tool" = "outil, maintenance, réparation, atelier"; +"system.icon.keywords.hammer" = "marteau, charpente"; +"system.icon.keywords.light" = "lumière, éclairage, lampe"; +"system.icon.keywords.bolt" = "courant, énergie, électrique"; +"system.icon.keywords.plug" = "prise, fiche"; +"system.icon.keywords.engine" = "moteur, générateur"; +"system.icon.keywords.fuel" = "carburant, diesel, essence"; +"system.icon.keywords.water" = "eau, pompe, réservoir"; +"system.icon.keywords.heat" = "chaleur, chauffage, chaudière, four"; +"system.icon.keywords.cold" = "froid, geler, refroidir"; +"system.icon.keywords.climate" = "climat, hvac, température"; // Direct strings "Systems" = "Systèmes"; diff --git a/Cable/nl.lproj/Localizable.strings b/Cable/nl.lproj/Localizable.strings index 1f6f6de..3ec1db3 100644 --- a/Cable/nl.lproj/Localizable.strings +++ b/Cable/nl.lproj/Localizable.strings @@ -44,6 +44,30 @@ "sample.load.lighting.name" = "LED-strips"; "sample.load.compressor.name" = "Luchtcompressor"; "sample.load.charger.name" = "Gereedschapslader"; +"system.icon.keywords.rv" = "camper, kampeerbus, buscamper, mobilhome, campervan"; +"system.icon.keywords.truck" = "vrachtwagen, trailer, aanhanger, truck"; +"system.icon.keywords.boat" = "boot, schip, jacht, zeil"; +"system.icon.keywords.plane" = "vliegtuig, vlucht, lucht"; +"system.icon.keywords.ferry" = "veerboot, ferry, schip"; +"system.icon.keywords.house" = "huis, thuis, hut, chalet, lodge"; +"system.icon.keywords.building" = "gebouw, kantoor, magazijn, fabriek, faciliteit"; +"system.icon.keywords.tent" = "kamperen, tent, buiten"; +"system.icon.keywords.solar" = "zonne, zon, zonnepaneel"; +"system.icon.keywords.battery" = "batterij, opslag, accu"; +"system.icon.keywords.server" = "server, data, netwerk, rack"; +"system.icon.keywords.computer" = "computer, elektronica, lab, tech"; +"system.icon.keywords.gear" = "tandwiel, mechanica, machine, werkplaats"; +"system.icon.keywords.tool" = "gereedschap, onderhoud, reparatie, werkplaats"; +"system.icon.keywords.hammer" = "hamer, timmerwerk"; +"system.icon.keywords.light" = "licht, verlichting, lamp"; +"system.icon.keywords.bolt" = "stroom, kracht, elektrisch, spanning"; +"system.icon.keywords.plug" = "stekker, aansluiting"; +"system.icon.keywords.engine" = "motor, generator"; +"system.icon.keywords.fuel" = "brandstof, diesel, benzine"; +"system.icon.keywords.water" = "water, pomp, tank, reservoir"; +"system.icon.keywords.heat" = "warmte, verwarming, kachel"; +"system.icon.keywords.cold" = "koud, vries, koel"; +"system.icon.keywords.climate" = "klimaat, hvac, temperatuur"; // Direct strings "Systems" = "Systemen"; diff --git a/CableTests/ComponentLibraryItemTests.swift b/CableTests/ComponentLibraryItemTests.swift new file mode 100644 index 0000000..08d780c --- /dev/null +++ b/CableTests/ComponentLibraryItemTests.swift @@ -0,0 +1,104 @@ +import Testing +@testable import Cable + +struct ComponentLibraryItemTests { + + @Test func localizedNameUsesExactLocaleMatch() async throws { + let item = ComponentLibraryItem( + id: "component-1", + name: "Anchor Winch", + translations: ["de_DE": "Ankerwinde"], + voltageIn: nil, + voltageOut: nil, + watt: nil, + iconURL: nil, + affiliateLinks: [] + ) + + let german = Locale(identifier: "de_DE") + #expect(item.localizedName(for: german) == "Ankerwinde") + } + + @Test func localizedNameFallsBackToBaseName() async throws { + let item = ComponentLibraryItem( + id: "component-2", + name: "Anchor Winch", + translations: [:], + voltageIn: nil, + voltageOut: nil, + watt: nil, + iconURL: nil, + affiliateLinks: [] + ) + + let french = Locale(identifier: "fr_FR") + #expect(item.localizedName(for: french) == "Anchor Winch") + } + + @Test func localizedNameDoesNotFallbackToSecondaryLanguages() async throws { + let item = ComponentLibraryItem( + id: "component-5", + name: "Anchor Winch", + translations: [ + "es_ES": "Molinete", + "de_DE": "Ankerwinde" + ], + voltageIn: nil, + voltageOut: nil, + watt: nil, + iconURL: nil, + affiliateLinks: [] + ) + + let languages = ["fr-FR", "de-DE", "es-ES"] + #expect(item.localizedName(usingPreferredLanguages: languages) == nil) + } + + @Test func localizedNameUsesLanguageOnlyMatch() async throws { + let item = ComponentLibraryItem( + id: "component-3", + name: "Anchor Winch", + translations: ["es": "Molinete"], + voltageIn: nil, + voltageOut: nil, + watt: nil, + iconURL: nil, + affiliateLinks: [] + ) + + let spanishMexico = Locale(identifier: "es_MX") + #expect(item.localizedName(for: spanishMexico) == "Molinete") + } + + @Test func localizedNameFallsBackToMatchingLanguageFromRegionalEntry() async throws { + let item = ComponentLibraryItem( + id: "component-6", + name: "Anchor Winch", + translations: ["de_DE": "Ankerwinde"], + voltageIn: nil, + voltageOut: nil, + watt: nil, + iconURL: nil, + affiliateLinks: [] + ) + + let germanSwitzerland = Locale(identifier: "de_CH") + #expect(item.localizedName(for: germanSwitzerland) == "Ankerwinde") + } + + @Test func localizedNameHandlesHyphenatedKeys() async throws { + let item = ComponentLibraryItem( + id: "component-4", + name: "Anchor Winch", + translations: ["fr-FR": "Guindeau"], + voltageIn: nil, + voltageOut: nil, + watt: nil, + iconURL: nil, + affiliateLinks: [] + ) + + let french = Locale(identifier: "fr_FR") + #expect(item.localizedName(for: french) == "Guindeau") + } +} diff --git a/CableUITestsScreenshot/CableUITestsScreenshot.swift b/CableUITestsScreenshot/CableUITestsScreenshot.swift index 0059e4c..5b3d4cc 100644 --- a/CableUITestsScreenshot/CableUITestsScreenshot.swift +++ b/CableUITestsScreenshot/CableUITestsScreenshot.swift @@ -8,34 +8,90 @@ import XCTest final class CableUITestsScreenshot: XCTestCase { + private let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard") override func setUpWithError() throws { - // Put setup code here. This method is called before the invocation of each test method in the class. - - // In UI tests it is usually best to stop immediately when a failure occurs. continueAfterFailure = false - - // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + try super.setUpWithError() + ensureDoNotDisturbEnabled() + dismissSystemOverlays() } override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. + try super.tearDownWithError() + dismissSystemOverlays() } @MainActor func testExample() throws { - // UI tests must launch the application that they test. let app = XCUIApplication() app.launch() - - // Use XCTAssert and related functions to verify your tests produce the correct results. + dismissSystemOverlays() } -// @MainActor -// func testLaunchPerformance() throws { -// // This measures how long it takes to launch your application. -// measure(metrics: [XCTApplicationLaunchMetric()]) { -// XCUIApplication().launch() -// } -// } + private func ensureDoNotDisturbEnabled() { + springboard.activate() + let pullStart = springboard.coordinate(withNormalizedOffset: CGVector(dx: 0.98, dy: 0.02)) + let pullEnd = springboard.coordinate(withNormalizedOffset: CGVector(dx: 0.98, dy: 0.30)) + pullStart.press(forDuration: 0.1, thenDragTo: pullEnd) + + let focusTile = springboard.otherElements["Focus"] + let focusButton = springboard.buttons["Focus"] + if focusTile.waitForExistence(timeout: 2) { + focusTile.press(forDuration: 1.0) + } else if focusButton.waitForExistence(timeout: 2) { + focusButton.press(forDuration: 1.0) + } + + let dndButton = springboard.buttons["Do Not Disturb"] + if dndButton.waitForExistence(timeout: 1) { + if !dndButton.isSelected { + dndButton.tap() + } + } else { + let dndCell = springboard.cells["Do Not Disturb"] + if dndCell.waitForExistence(timeout: 1) && !dndCell.isSelected { + dndCell.tap() + } else { + let dndLabel = springboard.staticTexts["Do Not Disturb"] + if dndLabel.waitForExistence(timeout: 1) { + dndLabel.tap() + } + } + } + + let dismissStart = springboard.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.85)) + let dismissEnd = springboard.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.15)) + dismissStart.press(forDuration: 0.1, thenDragTo: dismissEnd) + } + + private func dismissSystemOverlays() { + let app = XCUIApplication() + let alertButtons = [ + "OK", "Allow", "Later", "Not Now", "Close", + "Continue", "Remind Me Later", "Maybe Later", + ] + + if app.alerts.firstMatch.exists { + handleAlerts(in: app, buttons: alertButtons) + } + + if springboard.alerts.firstMatch.exists || springboard.scrollViews.firstMatch.exists { + handleAlerts(in: springboard, buttons: alertButtons + ["Enable Later"]) + } + } + + private func handleAlerts(in application: XCUIApplication, buttons: [String]) { + for buttonLabel in buttons { + let button = application.buttons[buttonLabel] + if button.waitForExistence(timeout: 0.5) { + button.tap() + return + } + } + let closeButton = application.buttons.matching(NSPredicate(format: "identifier CONTAINS[c] %@", "Close")).firstMatch + if closeButton.exists { + closeButton.tap() + } + } } diff --git a/frame_screens.sh b/frame_screens.sh index 64d79be..e71bdcd 100755 --- a/frame_screens.sh +++ b/frame_screens.sh @@ -1,11 +1,58 @@ #!/bin/bash set -euo pipefail FONT_COLOR="#3C3C3C" # color for light text -FONT_BOLD_COLOR="#B51700" # color for bold texto pipefail +FONT_BOLD_COLOR="#B51700" # color for bold text + +ONLY_IPHONE=false + +usage() { + cat <<'EOF' +Usage: frame_screens.sh [--iphone-only] [SRC_ROOT] [BG_IMAGE] [OUT_ROOT] + + --iphone-only Only frame screenshots whose device slug is not iPad. + SRC_ROOT Root folder with device/lang subfolders (default: Shots/Screenshots) + BG_IMAGE Background image to use (default: Shots/frame-bg.png) + OUT_ROOT Output folder for framed shots (default: Shots/Framed) +EOF +} + +POSITIONAL_ARGS=() +while [[ $# -gt 0 ]]; do + case "$1" in + --iphone-only) + ONLY_IPHONE=true + shift + ;; + -h|--help) + usage + exit 0 + ;; + --) + shift + POSITIONAL_ARGS+=("$@") + break + ;; + -*) + echo "Unknown option: $1" >&2 + usage >&2 + exit 1 + ;; + *) + POSITIONAL_ARGS+=("$1") + shift + ;; + esac +done + +if ((${#POSITIONAL_ARGS[@]})); then + set -- "${POSITIONAL_ARGS[@]}" +else + set -- +fi # Inputs -SRC_ROOT="${1:-Shots/Screenshots}" # root folder with lang subfolders (de/, fr/, en/…) -BG_IMAGE="${2:-Shots/frame-bg.png}" # background image (portrait) +SRC_ROOT="${1:-Shots/Screenshots}" # root folder with device/lang subfolders (iphone-17-pro-max/en/, ipad-pro-13-inch-m4/de/…) +BG_IMAGE="${2:-Shots/frame-bg.png}" # default background image OUT_ROOT="${3:-Shots/Framed}" # output folder FONT="./Shots/Fonts/Oswald-Light.ttf" # font for title text FONT_BOLD="./Shots/Fonts/Oswald-SemiBold.ttf" # font for *emphasized* text @@ -13,12 +60,22 @@ FONT_BOLD="./Shots/Fonts/Oswald-SemiBold.ttf" # font for *emphasized* text # Tweakables CORNER_RADIUS="auto" # corner radius; "auto" picks a good value based on width INSET=2 # inset (px) to shave off simulator’s black edge pixels -SHADOW_OPACITY=60 # 0–100 +SHADOW_OPACITY=0 # 0–100 SHADOW_BLUR=20 # blur radius SHADOW_OFFSET_X=0 # px SHADOW_OFFSET_Y=40 # px -CANVAS_MARGIN=190 # margin around the device on the background, px -TITLE_MARGIN=120 # margin above the device for title text, px +CANVAS_MARGIN=245 # default margin around the device on the background, px +TITLE_MARGIN=378 # default margin above the device for title text, px +TITLE_LINE_SPACING=220 # vertical distance between lines of the title text, px + +# Device-specific overrides (can be tuned via env vars) +TARGET_WIDTH_PHONE="${TARGET_WIDTH_PHONE:-1320}" +TARGET_HEIGHT_PHONE="${TARGET_HEIGHT_PHONE:-2868}" +TARGET_WIDTH_IPAD="${TARGET_WIDTH_IPAD:-2048}" +TARGET_HEIGHT_IPAD="${TARGET_HEIGHT_IPAD:-2732}" +IPAD_BG_IMAGE="${IPAD_BG_IMAGE:-$BG_IMAGE}" +IPAD_CANVAS_MARGIN="${IPAD_CANVAS_MARGIN:-240}" +IPAD_TITLE_MARGIN="${IPAD_TITLE_MARGIN:-180}" mkdir -p "$OUT_ROOT" @@ -28,29 +85,43 @@ render_mixed_font_title() { local title_text="$2" local title_y="$3" local output="$4" - - if [[ "$title_text" == *"*"* ]]; then - # Get canvas dimensions - read -r canvas_w canvas_h <<<"$(identify -format "%w %h" "$canvas")" - - # Create a temporary image to measure and render text parts - local temp_img - temp_img="$(mktemp /tmp/text_temp.XXXXXX_$$.png)" - cp "$canvas" "$temp_img" - - # Parse text into segments with their font types - declare -a text_segments=() - declare -a font_types=() - + + local expanded_title + expanded_title="$(printf '%b' "$title_text")" + + local temp_img + temp_img="$(mktemp /tmp/text_temp.XXXXXX_$$.png)" + cp "$canvas" "$temp_img" + + read -r canvas_w canvas_h <<<"$(identify -format "%w %h" "$canvas")" + + local -a lines=() + while IFS= read -r line || [[ -n "$line" ]]; do + lines+=("$line") + done < <(printf '%s' "$expanded_title") + + if ((${#lines[@]} == 0)); then + lines+=("$expanded_title") + fi + + if ((${#lines[@]} > 2)); then + lines=("${lines[@]:0:2}") + fi + + for idx in "${!lines[@]}"; do + local line="${lines[$idx]}" + local current_y=$((title_y + idx * TITLE_LINE_SPACING)) + + local -a text_segments=() + local -a font_types=() local current_text="" local in_bold=false local i=0 - - while [ $i -lt ${#title_text} ]; do - local char="${title_text:$i:1}" - + local line_length=${#line} + + while [ $i -lt $line_length ]; do + local char="${line:$i:1}" if [[ "$char" == "*" ]]; then - # Save current segment (even if empty, to handle cases like "**") text_segments+=("$current_text") if [[ "$in_bold" == true ]]; then font_types+=("bold") @@ -58,7 +129,6 @@ render_mixed_font_title() { font_types+=("light") fi current_text="" - # Toggle bold state if [[ "$in_bold" == true ]]; then in_bold=false else @@ -69,95 +139,62 @@ render_mixed_font_title() { fi i=$((i + 1)) done - - # Handle remaining text - if [[ -n "$current_text" ]]; then - text_segments+=("$current_text") - if [[ "$in_bold" == true ]]; then - font_types+=("bold") - else - font_types+=("light") - fi + + text_segments+=("$current_text") + if [[ "$in_bold" == true ]]; then + font_types+=("bold") + else + font_types+=("light") fi - - # Debug: print segments (remove this later) - echo "DEBUG: Text segments:" - local debug_i=0 - while [ $debug_i -lt ${#text_segments[@]} ]; do - echo " [$debug_i]: '${text_segments[$debug_i]}' (${font_types[$debug_i]})" - debug_i=$((debug_i + 1)) - done - - # Calculate total width + local total_width=0 - local j=0 - while [ $j -lt ${#text_segments[@]} ]; do + for ((j = 0; j < ${#text_segments[@]}; j++)); do local segment="${text_segments[$j]}" - local font_type="${font_types[$j]}" - - # Skip empty segments for width calculation if [[ -n "$segment" ]]; then local font_for_measurement="$FONT" - if [[ "$font_type" == "bold" ]]; then + if [[ "${font_types[$j]}" == "bold" ]]; then font_for_measurement="$FONT_BOLD" fi - - # Replace leading/trailing spaces with non-breaking spaces for measurement local segment_for_measurement="$segment" - segment_for_measurement="${segment_for_measurement/#/ }" # leading space - segment_for_measurement="${segment_for_measurement/%/ }" # trailing space - - local part_width=$(magick -font "$font_for_measurement" -pointsize 148 -size x label:"$segment_for_measurement" -format "%w" info:) + segment_for_measurement="${segment_for_measurement/#/ }" + segment_for_measurement="${segment_for_measurement/%/ }" + local part_width + part_width=$(magick -font "$font_for_measurement" -pointsize 148 -size x label:"$segment_for_measurement" -format "%w" info:) total_width=$((total_width + part_width)) fi - j=$((j + 1)) done - - # Calculate starting X position to center the entire text + + if (( total_width <= 0 )); then + continue + fi + local start_x=$(( (canvas_w - total_width) / 2 )) - - # Render each segment local x_offset=0 - j=0 - while [ $j -lt ${#text_segments[@]} ]; do + for ((j = 0; j < ${#text_segments[@]}; j++)); do local segment="${text_segments[$j]}" - local font_type="${font_types[$j]}" - - # Skip empty segments for rendering if [[ -n "$segment" ]]; then local font_to_use="$FONT" local color_to_use="$FONT_COLOR" - if [[ "$font_type" == "bold" ]]; then + if [[ "${font_types[$j]}" == "bold" ]]; then font_to_use="$FONT_BOLD" color_to_use="$FONT_BOLD_COLOR" fi - - # Replace leading/trailing spaces with non-breaking spaces for rendering local segment_for_rendering="$segment" - segment_for_rendering="${segment_for_rendering/#/ }" # leading space - segment_for_rendering="${segment_for_rendering/%/ }" # trailing space - + segment_for_rendering="${segment_for_rendering/#/ }" + segment_for_rendering="${segment_for_rendering/%/ }" magick "$temp_img" \ -font "$font_to_use" -pointsize 148 -fill "$color_to_use" \ - -gravity northwest -annotate "+$((start_x + x_offset))+${title_y}" "$segment_for_rendering" \ + -gravity northwest -annotate "+$((start_x + x_offset))+${current_y}" "$segment_for_rendering" \ "$temp_img" - - # Calculate width of rendered text for next position (use same processed segment) - local text_width=$(magick -font "$font_to_use" -pointsize 148 -size x label:"$segment_for_rendering" -format "%w" info:) + local text_width + text_width=$(magick -font "$font_to_use" -pointsize 148 -size x label:"$segment_for_rendering" -format "%w" info:) x_offset=$((x_offset + text_width)) fi - j=$((j + 1)) done - - cp "$temp_img" "$output" - rm -f "$temp_img" - else - # No asterisks, simple rendering - magick "$canvas" \ - -font "$FONT" -pointsize 148 -fill "$FONT_COLOR" \ - -gravity north -annotate "+0+${title_y}" "$title_text" \ - "$output" - fi + done + + cp "$temp_img" "$output" + rm -f "$temp_img" } # Function to get title from config file @@ -189,11 +226,15 @@ get_title() { # Function to frame one screenshot frame_one () { - local in="$1" # input screenshot (e.g., 1320x2868) - local out="$2" # output image + local in="$1" # input screenshot (e.g., 1320x2868) + local out="$2" # output image local bg="$3" - local lang="$4" # language code (e.g., "de", "en") - local screenshot_name="$5" # screenshot filename + local lang="$4" # language code (e.g., "de", "en") + local screenshot_name="$5" # screenshot filename + local target_width="$6" + local target_height="$7" + local canvas_margin="$8" + local title_margin="$9" # Read sizes read -r W H <<<"$(identify -format "%w %h" "$in")" @@ -230,8 +271,8 @@ frame_one () { # Compose on the background, centered # First, scale background to be at least screenshot+margin in both dimensions read -r BW BH <<<"$(identify -format "%w %h" "$bg")" - local minW=$((W + 2*CANVAS_MARGIN)) - local minH=$((H + 2*CANVAS_MARGIN + TITLE_MARGIN)) + local minW=$((W + 2*canvas_margin)) + local minH=$((H + 2*canvas_margin + title_margin)) local canvas canvas="$(mktemp /tmp/canvas.XXXXXX_$$.png)" magick "$bg" -resize "${minW}x${minH}^" -gravity center -extent "${minW}x${minH}" "$canvas" @@ -242,35 +283,125 @@ frame_one () { with_title="$(mktemp /tmp/with_title.XXXXXX_$$.png)" # Calculate title position (center horizontally, positioned above the screenshot) - local title_y=$((TITLE_MARGIN - 10)) # 10px from top of title margin + local title_y=$((title_margin - 100)) # 10px from top of title margin # Render title with mixed fonts render_mixed_font_title "$canvas" "$title_text" "$title_y" "$with_title" # Now place shadow (which already includes the rounded image) positioned below the title # Calculate the vertical offset to center the screenshot in the remaining space below the title - local screenshot_offset=$((TITLE_MARGIN*2)) + local screenshot_offset=$((title_margin*2)) local temp_result temp_result="$(mktemp /tmp/temp_result.XXXXXX_$$.png)" magick "$with_title" "$shadow" -gravity center -geometry "+0+${screenshot_offset}" -compose over -composite "$temp_result" # Final step: scale to exact dimensions 1320 × 2868px - magick "$temp_result" -resize "1320x2868^" -gravity center -extent "1320x2868" "$out" + magick "$temp_result" -resize "${target_width}x${target_height}^" -gravity center -extent "${target_width}x${target_height}" "$out" rm -f "$mask" "$rounded" "$shadow" "$canvas" "$with_title" "$temp_result" } # Process all screenshots in SRC_ROOT/*/*.png +resolve_device_profile() { + local device_slug="$1" + + PROFILE_BG="$BG_IMAGE" + PROFILE_TARGET_WIDTH="$TARGET_WIDTH_PHONE" + PROFILE_TARGET_HEIGHT="$TARGET_HEIGHT_PHONE" + PROFILE_CANVAS_MARGIN="$CANVAS_MARGIN" + PROFILE_TITLE_MARGIN="$TITLE_MARGIN" + + if [[ -n "$device_slug" ]]; then + local slug_lower + slug_lower="$(printf '%s' "$device_slug" | tr '[:upper:]' '[:lower:]')" + if [[ "$slug_lower" == *"ipad"* ]]; then + PROFILE_BG="$IPAD_BG_IMAGE" + PROFILE_TARGET_WIDTH="$TARGET_WIDTH_IPAD" + PROFILE_TARGET_HEIGHT="$TARGET_HEIGHT_IPAD" + PROFILE_CANVAS_MARGIN="$IPAD_CANVAS_MARGIN" + PROFILE_TITLE_MARGIN="$IPAD_TITLE_MARGIN" + fi + fi +} + +process_lang_dir() { + local lang_path="$1" + local lang="$2" + local device_slug="$3" + + local out_dir="$OUT_ROOT" + local log_prefix="$lang" + + if [[ -n "$device_slug" ]]; then + out_dir="$out_dir/$device_slug" + log_prefix="$device_slug/$lang" + fi + + out_dir="$out_dir/$lang" + mkdir -p "$out_dir" + + resolve_device_profile "$device_slug" + + shopt -s nullglob + for shot in "$lang_path"/*.png; do + local base="$(basename "$shot")" + frame_one \ + "$shot" \ + "$out_dir/$base" \ + "$PROFILE_BG" \ + "$lang" \ + "$base" \ + "$PROFILE_TARGET_WIDTH" \ + "$PROFILE_TARGET_HEIGHT" \ + "$PROFILE_CANVAS_MARGIN" \ + "$PROFILE_TITLE_MARGIN" + echo "Framed: $log_prefix/$base" + done +} + shopt -s nullglob -for langdir in "$SRC_ROOT"/*; do - [[ -d "$langdir" ]] || continue - rel="$(basename "$langdir")" - mkdir -p "$OUT_ROOT/$rel" - for shot in "$langdir"/*.png; do - base="$(basename "$shot")" - frame_one "$shot" "$OUT_ROOT/$rel/$base" "$BG_IMAGE" "$rel" "$base" - echo "Framed: $rel/$base" +found_any=false +skipped_for_device=false +for entry in "$SRC_ROOT"/*; do + [[ -d "$entry" ]] || continue + entry_basename="$(basename "$entry")" + entry_lower="$(printf '%s' "$entry_basename" | tr '[:upper:]' '[:lower:]')" + if [[ "$ONLY_IPHONE" == true && "$entry_lower" == *"ipad"* ]]; then + skipped_for_device=true + continue + fi + + pattern="${entry%/}/*.png" + if compgen -G "$pattern" > /dev/null; then + process_lang_dir "$entry" "$(basename "$entry")" "" + found_any=true + continue + fi + + for langdir in "$entry"/*; do + [[ -d "$langdir" ]] || continue + if [[ "$ONLY_IPHONE" == true ]]; then + lang_device_slug="$(basename "$entry")" + lang_slug_lower="$(printf '%s' "$lang_device_slug" | tr '[:upper:]' '[:lower:]')" + if [[ "$lang_slug_lower" == *"ipad"* ]]; then + skipped_for_device=true + continue + fi + fi + pattern="${langdir%/}/*.png" + if compgen -G "$pattern" > /dev/null; then + process_lang_dir "$langdir" "$(basename "$langdir")" "$(basename "$entry")" + found_any=true + fi done done -echo "Done. Framed images in: $OUT_ROOT/" \ No newline at end of file +if [[ "$found_any" == false ]]; then + if [[ "$ONLY_IPHONE" == true && "$skipped_for_device" == true ]]; then + echo "No iPhone screenshots found under $SRC_ROOT" >&2 + else + echo "No screenshots found under $SRC_ROOT" >&2 + fi +fi + +echo "Done. Framed images in: $OUT_ROOT/" diff --git a/shooter.sh b/shooter.sh index 00e41cc..33ed023 100755 --- a/shooter.sh +++ b/shooter.sh @@ -2,8 +2,22 @@ set -euo pipefail SCHEME="CableScreenshots" -DEVICE="iPhone 17 Pro Max" -RUNTIME_OS="26.0" # e.g. "18.1". Leave empty to let Xcode pick. +RESET_SIMULATOR="${RESET_SIMULATOR:-1}" +APP_BUNDLE_ID="${APP_BUNDLE_ID:-app.voltplan.CableApp}" +UITEST_BUNDLE_ID="${UITEST_BUNDLE_ID:-com.yuzuhub.CableUITestsScreenshot}" + +is_truthy() { + case "$1" in + 1|true|TRUE|yes|YES|on|ON) return 0 ;; + 0|false|FALSE|no|NO|off|OFF|"") return 1 ;; + *) return 0 ;; + esac +} + +DEVICE_MATRIX=( + "iPad Pro Screenshot|26.0|ipad-pro-13-inch-m4" + "iPhone 17 Pro Max|26.0|iphone-17-pro-max" +) command -v xcparse >/dev/null 2>&1 || { echo "xcparse not found. Install with: brew install chargepoint/xcparse/xcparse" >&2 @@ -23,53 +37,65 @@ resolve_udid() { fi } -for lang in de fr en es nl; do - # Erase all content and settings to ensure a clean simulator state - echo "Resetting simulator for a clean start..." - UDID=$(resolve_udid "$DEVICE" "$RUNTIME_OS") - if [[ -z "$UDID" ]]; then - # Fallback: pick any matching (booted or shutdown) - UDID=$(xcrun simctl list devices | awk -v n="$DEVICE" -F '[()]' '$0 ~ n {print $2; exit}') - fi - if [[ -z "$UDID" ]]; then - echo "Could not resolve UDID for $DEVICE" >&2; exit 1 - fi - # Ensure the device is not booted, then fully erase it. Do NOT ignore failures here. - xcrun simctl shutdown "$UDID" || true - xcrun simctl erase "$UDID" - echo "Running screenshots for $lang" - region=$(echo "$lang" | tr '[:lower:]' '[:upper:]') +for device_entry in "${DEVICE_MATRIX[@]}"; do + IFS='|' read -r DEVICE_NAME DEVICE_RUNTIME DEVICE_SLUG <<<"$device_entry" + echo "=== Device: $DEVICE_NAME (runtime: ${DEVICE_RUNTIME:-auto}) ===" - # Resolve simulator UDID and enforce system language/locale on the simulator itself - UDID=$(resolve_udid "$DEVICE" "$RUNTIME_OS") - if [[ -z "$UDID" ]]; then - # Fallback: pick any matching (booted or shutdown) - UDID=$(xcrun simctl list devices | awk -v n="$DEVICE" -F '[()]' '$0 ~ n {print $2; exit}') - fi - if [[ -z "$UDID" ]]; then - echo "Could not resolve UDID for $DEVICE" >&2; exit 1 - fi + for lang in de fr en es nl; do + echo "Resetting simulator for a clean start..." + UDID=$(resolve_udid "$DEVICE_NAME" "$DEVICE_RUNTIME") + if [[ -z "$UDID" ]]; then + UDID=$(xcrun simctl list devices | awk -v n="$DEVICE_NAME" -F '[()]' '$0 ~ n {print $2; exit}') + fi + if [[ -z "$UDID" ]]; then + echo "Could not resolve UDID for $DEVICE_NAME" >&2; exit 1 + fi - # Boot, set system language & locale, then restart the simulator to ensure it sticks - xcrun simctl boot "$UDID" || true - xcrun simctl spawn "$UDID" defaults write 'Apple Global Domain' AppleLanguages -array "$lang" - xcrun simctl spawn "$UDID" defaults write 'Apple Global Domain' AppleLocale "${lang}_${region}" - # Some versions require a reboot of the sim for language changes to fully apply - xcrun simctl shutdown "$UDID" || true - xcrun simctl boot "$UDID" + xcrun simctl shutdown "$UDID" || true + if is_truthy "$RESET_SIMULATOR"; then + xcrun simctl erase "$UDID" + else + for bundle in "$APP_BUNDLE_ID" "$UITEST_BUNDLE_ID"; do + if [[ -n "$bundle" ]]; then + xcrun simctl terminate "$UDID" "$bundle" || true + xcrun simctl uninstall "$UDID" "$bundle" || true + fi + done + fi + echo "Running screenshots for $lang" + region=$(echo "$lang" | tr '[:lower:]' '[:upper:]') - bundle="results-$lang.xcresult" - outdir="Shots/Screenshots/$lang" - rm -rf "$bundle" "$outdir" - mkdir -p "$outdir" + UDID=$(resolve_udid "$DEVICE_NAME" "$DEVICE_RUNTIME") + if [[ -z "$UDID" ]]; then + UDID=$(xcrun simctl list devices | awk -v n="$DEVICE_NAME" -F '[()]' '$0 ~ n {print $2; exit}') + fi + if [[ -z "$UDID" ]]; then + echo "Could not resolve UDID for $DEVICE_NAME" >&2; exit 1 + fi - # Note: Simulator system language/locale is enforced via simctl (AppleLanguages/AppleLocale) before each run. - xcodebuild test \ - -scheme "$SCHEME" \ - -destination "id=$UDID" \ - -resultBundlePath "$bundle" + xcrun simctl boot "$UDID" || true + xcrun simctl spawn "$UDID" defaults write 'Apple Global Domain' AppleLanguages -array "$lang" + xcrun simctl spawn "$UDID" defaults write 'Apple Global Domain' AppleLocale "${lang}_${region}" + xcrun simctl shutdown "$UDID" || true + xcrun simctl boot "$UDID" + xcrun simctl status_bar booted override \ + --time "9:41" \ + --batteryState charged --batteryLevel 100 \ + --wifiBars 3 + - xcparse screenshots "$bundle" "$outdir" - echo "Exported screenshots to $outdir" - xcrun simctl shutdown "$UDID" || true -done \ No newline at end of file + bundle="results-${DEVICE_SLUG}-${lang}.xcresult" + outdir="Shots/Screenshots/${DEVICE_SLUG}/$lang" + rm -rf "$bundle" "$outdir" + mkdir -p "$outdir" + + xcodebuild test \ + -scheme "$SCHEME" \ + -destination "id=$UDID" \ + -resultBundlePath "$bundle" + + xcparse screenshots "$bundle" "$outdir" + echo "Exported screenshots to $outdir" + xcrun simctl shutdown "$UDID" || true + done +done