diff --git a/Aerial.xcodeproj/project.pbxproj b/Aerial.xcodeproj/project.pbxproj index 7dc73435..f2a6fd0d 100644 --- a/Aerial.xcodeproj/project.pbxproj +++ b/Aerial.xcodeproj/project.pbxproj @@ -29,6 +29,8 @@ 035A92A7225F8C480095AB85 /* de.json in Resources */ = {isa = PBXBuildFile; fileRef = 035A92A4225F8C480095AB85 /* de.json */; }; 035A92A8225F8C480095AB85 /* he.json in Resources */ = {isa = PBXBuildFile; fileRef = 035A92A5225F8C480095AB85 /* he.json */; }; 035A92A9225F8C480095AB85 /* he.json in Resources */ = {isa = PBXBuildFile; fileRef = 035A92A5225F8C480095AB85 /* he.json */; }; + 035A92AC226754760095AB85 /* ar.json in Resources */ = {isa = PBXBuildFile; fileRef = 035A92AB226754760095AB85 /* ar.json */; }; + 035A92AD226754760095AB85 /* ar.json in Resources */ = {isa = PBXBuildFile; fileRef = 035A92AB226754760095AB85 /* ar.json */; }; 0369985D2196103300E359D3 /* missingvideos.json in Resources */ = {isa = PBXBuildFile; fileRef = 0369985C2196103300E359D3 /* missingvideos.json */; }; 0369985E2196129C00E359D3 /* missingvideos.json in Resources */ = {isa = PBXBuildFile; fileRef = 0369985C2196103300E359D3 /* missingvideos.json */; }; 03893CB3217749F0008E7125 /* ErrorLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03893CB2217749F0008E7125 /* ErrorLog.swift */; }; @@ -114,6 +116,7 @@ 03510C722185EF76008F74F2 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; 035A92A4225F8C480095AB85 /* de.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = de.json; sourceTree = ""; }; 035A92A5225F8C480095AB85 /* he.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = he.json; sourceTree = ""; }; + 035A92AB226754760095AB85 /* ar.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ar.json; sourceTree = ""; }; 0369985C2196103300E359D3 /* missingvideos.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = missingvideos.json; sourceTree = ""; }; 03893CB2217749F0008E7125 /* ErrorLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorLog.swift; sourceTree = ""; }; 039385792175D4B80040B850 /* AVPlayerViewExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVPlayerViewExtension.swift; sourceTree = ""; }; @@ -199,6 +202,7 @@ 033192DF217B77E90073B580 /* Community */ = { isa = PBXGroup; children = ( + 035A92AB226754760095AB85 /* ar.json */, 035A92A4225F8C480095AB85 /* de.json */, 035A92A5225F8C480095AB85 /* he.json */, 03D3DAC3221F286700BDA52F /* pl.json */, @@ -526,6 +530,7 @@ 0369985E2196129C00E359D3 /* missingvideos.json in Resources */, 033D62B0216CAE2C00F3AF83 /* icon-night-dark.pdf in Resources */, 0395835621807D1F008E8F9C /* thumbnail.png in Resources */, + 035A92AD226754760095AB85 /* ar.json in Resources */, 03D3DAC5221F286D00BDA52F /* pl.json in Resources */, FAC36F481BE1756D007F2A20 /* Assets.xcassets in Resources */, 033D62AC216CADCD00F3AF83 /* icon-day-dark.pdf in Resources */, @@ -554,6 +559,7 @@ FAC36F531BE1756D007F2A20 /* PreferencesWindow.xib in Resources */, 035A92A6225F8C480095AB85 /* de.json in Resources */, 03D37FDB22145487005A146F /* fr.json in Resources */, + 035A92AC226754760095AB85 /* ar.json in Resources */, FAC36F4D1BE1756D007F2A20 /* icon-day.pdf in Resources */, 035A92A8225F8C480095AB85 /* he.json in Resources */, 03D3DAC4221F286700BDA52F /* pl.json in Resources */, diff --git a/Aerial.xcodeproj/xcshareddata/xcschemes/Aerial.xcscheme b/Aerial.xcodeproj/xcshareddata/xcschemes/Aerial.xcscheme index f94b9ebb..1c365d60 100644 --- a/Aerial.xcodeproj/xcshareddata/xcschemes/Aerial.xcscheme +++ b/Aerial.xcodeproj/xcshareddata/xcschemes/Aerial.xcscheme @@ -76,5 +76,14 @@ + + + + + + diff --git a/Aerial/Source/Controllers/Preferences.swift b/Aerial/Source/Controllers/Preferences.swift index 4b11d7d7..89959906 100644 --- a/Aerial/Source/Controllers/Preferences.swift +++ b/Aerial/Source/Controllers/Preferences.swift @@ -68,6 +68,7 @@ final class Preferences { case darkModeNightOverride = "darkModeNightOverride" case newVideosMode = "newVideosMode" case lastVideoCheck = "lastVideoCheck" + case ciOverrideLanguage = "ciOverrideLanguage" } enum NewVideosMode: Int { @@ -183,6 +184,7 @@ final class Preferences { defaultValues[.alternateVideoFormat] = AlternateVideoFormat.powerSaving defaultValues[.darkModeNightOverride] = false defaultValues[.newVideosMode] = NewVideosMode.weekly + defaultValues[.ciOverrideLanguage] = "" // Set today's date as default let dateFormatter = DateFormatter() @@ -399,6 +401,15 @@ final class Preferences { } } + var ciOverrideLanguage: String? { + get { + return optionalValue(forIdentifier: .ciOverrideLanguage) + } + set { + setValue(forIdentifier: .ciOverrideLanguage, value: newValue) + } + } + var latitude: String? { get { return optionalValue(forIdentifier: .latitude) diff --git a/Aerial/Source/Controllers/PreferencesWindowController.swift b/Aerial/Source/Controllers/PreferencesWindowController.swift index b64a196d..aa1241db 100644 --- a/Aerial/Source/Controllers/PreferencesWindowController.swift +++ b/Aerial/Source/Controllers/PreferencesWindowController.swift @@ -77,6 +77,7 @@ final class PreferencesWindowController: NSWindowController, NSOutlineViewDataSo @IBOutlet var fadeInOutModePopup: NSPopUpButton! @IBOutlet weak var fadeInOutTextModePopup: NSPopUpButton! + @IBOutlet var ciOverrideLanguagePopup: NSPopUpButton! @IBOutlet weak var downloadProgressIndicator: NSProgressIndicator! @IBOutlet weak var downloadStopButton: NSButton! @@ -350,6 +351,11 @@ final class PreferencesWindowController: NSWindowController, NSOutlineViewDataSo currentLocaleLabel.stringValue = "" } + let poisp = PoiStringProvider.sharedInstance + + // Should we override the community language ? + ciOverrideLanguagePopup.selectItem(at: poisp.getLanguagePosition()) + // Videos panel playerView.player = player playerView.controlsStyle = .none @@ -871,6 +877,12 @@ final class PreferencesWindowController: NSWindowController, NSOutlineViewDataSo debugLog("UI useCommunity: \(onState)") } + @IBAction func communityLanguagePopupChange(_ sender: NSPopUpButton) { + debugLog("UI communityLanguagePopupChange: \(sender.indexOfSelectedItem)") + let poisp = PoiStringProvider.sharedInstance + preferences.ciOverrideLanguage = poisp.getLanguageStringFromPosition(pos: sender.indexOfSelectedItem) + } + @IBAction func localizeForTvOS12Click(button: NSButton?) { let state = localizeForTvOS12Checkbox.state let onState = state == .on diff --git a/Aerial/Source/Models/Cache/PoiStringProvider.swift b/Aerial/Source/Models/Cache/PoiStringProvider.swift index 9a77c1d9..f5597b3e 100644 --- a/Aerial/Source/Models/Cache/PoiStringProvider.swift +++ b/Aerial/Source/Models/Cache/PoiStringProvider.swift @@ -85,7 +85,7 @@ final class PoiStringProvider { let locale: NSLocale = NSLocale(localeIdentifier: Locale.preferredLanguages[0]) if #available(OSX 10.12, *) { - if preferences.localizeDescriptions && locale.languageCode != communityLanguage { + if preferences.localizeDescriptions && locale.languageCode != communityLanguage && preferences.ciOverrideLanguage == "" { return stringBundle!.localizedString(forKey: key, value: "", table: "Localizable.nocache") } } @@ -115,7 +115,7 @@ final class PoiStringProvider { let locale: NSLocale = NSLocale(localeIdentifier: Locale.preferredLanguages[0]) if #available(OSX 10.12, *) { debugLog("locale.languageCode \(locale.languageCode)") - if preferences.localizeDescriptions && locale.languageCode != communityLanguage { + if preferences.localizeDescriptions && locale.languageCode != communityLanguage && preferences.ciOverrideLanguage == "" { return video.poi } } @@ -128,11 +128,24 @@ final class PoiStringProvider { } // MARK: - Community data - + // swiftlint:disable:next cyclomatic_complexity private func getCommunityPathForLocale() -> String { let preferences = Preferences.sharedInstance let locale: NSLocale = NSLocale(localeIdentifier: Locale.preferredLanguages[0]) + // Do we have a community language override ? + if preferences.localizeDescriptions && preferences.ciOverrideLanguage != "" { + let path = Bundle(for: PoiStringProvider.self).path(forResource: preferences.ciOverrideLanguage, ofType: "json") + if path != nil { + let fileManager = FileManager.default + if fileManager.fileExists(atPath: path!) { + debugLog("Community Language overriden to : \(preferences.ciOverrideLanguage!)") + communityLanguage = preferences.ciOverrideLanguage! + return path! + } + } + } + if #available(OSX 10.12, *) { // First we look in the Cache Folder for a locale directory let cacheDirectory = VideoCache.cacheDirectory! @@ -163,7 +176,7 @@ final class PoiStringProvider { let cc = locale.languageCode // Just in case, cause we had a crash earlier with the fr one for some reason... // This is probably no longer needed - if cc == "en" || cc == "es" || cc == "fr" || cc == "pl" || cc == "de" || cc == "he" { + if cc == "en" || cc == "es" || cc == "fr" || cc == "pl" || cc == "de" || cc == "he" || cc == "ar" { if preferences.localizeDescriptions { let path = Bundle(for: PoiStringProvider.self).path(forResource: cc, ofType: "json") if path != nil { @@ -217,4 +230,49 @@ final class PoiStringProvider { func getCommunityPoi(id: String) -> [String: String] { return communityStrings.first(where: { $0.id == id }).map { $0.poi } ?? [:] } + + // Helpers for the main popup + func getLanguagePosition() -> Int { + let preferences = Preferences.sharedInstance + // The list is alphabetized based on their english name in the UI + switch preferences.ciOverrideLanguage { + case "ar": // Arabic + return 1 + case "en": // English + return 2 + case "fr": // French + return 3 + case "de": // German + return 4 + case "he": // Hebrew + return 5 + case "pl": // Polish + return 6 + case "es": // Spanish + return 7 + default: // This is the default, preferred language + return 0 + } + } + + func getLanguageStringFromPosition(pos: Int) -> String { + switch pos { + case 1: + return "ar" + case 2: + return "en" + case 3: + return "fr" + case 4: + return "de" + case 5: + return "he" + case 6: + return "pl" + case 7: + return "es" + default: + return "" + } + } } diff --git a/Aerial/Source/Views/AerialView.swift b/Aerial/Source/Views/AerialView.swift index 6990281c..f26a0741 100644 --- a/Aerial/Source/Views/AerialView.swift +++ b/Aerial/Source/Views/AerialView.swift @@ -91,6 +91,7 @@ final class AerialView: ScreenSaverView { class var sharedPlayer: AVPlayer { struct Static { static let instance: AVPlayer = AVPlayer() + // swiftlint:disable:next identifier_name static var _player: AVPlayer? static var player: AVPlayer { if let activePlayer = _player { diff --git a/Resources/Info.plist b/Resources/Info.plist index 8a581bf1..8e791f63 100644 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.4.7beta7 + 1.4.7beta8 CFBundleSignature ???? CFBundleVersion - 1.4.7beta7 + 1.4.7beta8 LSApplicationCategoryType LSMinimumSystemVersion diff --git a/Resources/PreferencesWindow.xib b/Resources/PreferencesWindow.xib index 238217ec..cfd18c99 100644 --- a/Resources/PreferencesWindow.xib +++ b/Resources/PreferencesWindow.xib @@ -1,9 +1,9 @@ - + - - + + @@ -17,6 +17,7 @@ + @@ -144,7 +145,7 @@ - + @@ -531,7 +532,7 @@ is disabled - + @@ -766,9 +767,9 @@ should appear + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +