1.0.2: Add multilingual support, redesign share view, and iCloud sync improvements

- Add localisations for German, French, Italian, and Brazilian Portuguese
- Redesign WeekPlanShareView with richer layout and sharing options
- Improve HomeView with various UI enhancements
- Update AppSettings and Tag models for new features
- Minor iCloud sync and Settings fixes
- Add archive & upload script for App Store submissions

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
alexandrev-tibco
2026-03-07 19:02:33 +01:00
parent 63c9ba57de
commit c66132f494
15 changed files with 1946 additions and 109 deletions
+41 -1
View File
@@ -16,6 +16,7 @@ final class AppSettings {
var eventPrefix: String
var reminderMinutesBefore: Int?
var iCloudSyncEnabled: Bool?
var weekExportStyle: String?
var isPremium: Bool
var onboardingCompleted: Bool
@@ -41,6 +42,7 @@ final class AppSettings {
self.eventPrefix = "🍽️"
self.reminderMinutesBefore = nil
self.iCloudSyncEnabled = true
self.weekExportStyle = nil
self.isPremium = false
self.onboardingCompleted = false
}
@@ -64,6 +66,11 @@ final class AppSettings {
get { iCloudSyncEnabled ?? true }
set { iCloudSyncEnabled = newValue }
}
var weekExportStyleEnum: WeekExportStyle {
get { WeekExportStyle(rawValue: weekExportStyle ?? "") ?? .defaultStyle }
set { weekExportStyle = newValue.rawValue }
}
}
enum MealWindows: String, CaseIterable {
@@ -92,12 +99,20 @@ enum AppLanguage: String, CaseIterable {
case system
case spanish
case english
case french
case german
case italian
case portugueseBrazil
var displayName: String {
switch self {
case .system: return "System"
case .spanish: return "Español"
case .english: return "English"
case .french: return "Français"
case .german: return "Deutsch"
case .italian: return "Italiano"
case .portugueseBrazil: return "Português (Brasil)"
}
}
@@ -106,12 +121,23 @@ enum AppLanguage: String, CaseIterable {
case .system: return resolved().localeIdentifier
case .spanish: return "es"
case .english: return "en"
case .french: return "fr"
case .german: return "de"
case .italian: return "it"
case .portugueseBrazil: return "pt-BR"
}
}
func resolved() -> AppLanguage {
if self != .system { return self }
return Locale.current.identifier.lowercased().hasPrefix("es") ? .spanish : .english
let localeIdentifier = Locale.current.identifier.lowercased()
if localeIdentifier.hasPrefix("es") { return .spanish }
if localeIdentifier.hasPrefix("fr") { return .french }
if localeIdentifier.hasPrefix("de") { return .german }
if localeIdentifier.hasPrefix("it") { return .italian }
if localeIdentifier.hasPrefix("pt") { return .portugueseBrazil }
return .english
}
}
@@ -138,3 +164,17 @@ enum CalendarSyncMode: String, CaseIterable {
}
}
}
enum WeekExportStyle: String, CaseIterable {
case defaultStyle
case schoolTimetable
case vertical
var localizedKey: String {
switch self {
case .defaultStyle: return "share_export_style_default"
case .schoolTimetable: return "share_export_style_school"
case .vertical: return "share_export_style_vertical"
}
}
}
+3 -3
View File
@@ -41,8 +41,8 @@ final class Tag {
func localizedName(language: AppLanguage) -> String {
switch language.resolved() {
case .spanish: return name
case .english: return nameEN.isEmpty ? name : nameEN
case .system: return name
case .english, .french, .german, .italian, .portugueseBrazil: return nameEN.isEmpty ? name : nameEN
case .system: return nameEN.isEmpty ? name : nameEN
}
}
@@ -57,7 +57,7 @@ final class Tag {
switch resolvedLanguage {
case .spanish:
parts.append("Max \(max)/semana")
case .english:
case .english, .french, .german, .italian, .portugueseBrazil:
parts.append("Max \(max)/week")
case .system:
parts.append("Max \(max)/week")