diff --git a/Passepartout/App/Extensions/PassepartoutProviders+Extensions.swift b/Passepartout/App/Extensions/PassepartoutProviders+Extensions.swift index 01cba642..cd9970d3 100644 --- a/Passepartout/App/Extensions/PassepartoutProviders+Extensions.swift +++ b/Passepartout/App/Extensions/PassepartoutProviders+Extensions.swift @@ -69,18 +69,30 @@ extension ProviderServer: Comparable { lhs.id == rhs.id } - // "Default" comes first - // sorts by serverIndex first, see ProtonVPN > Germany (currently "Frankfurt #203" comes before "#3") + // "Default" comes first (nil localizedName) public static func <(lhs: Self, rhs: Self) -> Bool { - if let li = lhs.serverIndex, let ri = rhs.serverIndex { + guard let ld = lhs.localizedName else { + return true + } + guard let rd = rhs.localizedName else { + return false + } + guard ld != rd else { + guard let li = lhs.serverIndex else { + return true + } + guard let ri = rhs.serverIndex else { + return false + } + guard li != ri else { + guard lhs.apiId != rhs.apiId else { + return lhs.tags?.joined() ?? "" < rhs.tags?.joined() ?? "" + } + return lhs.apiId < rhs.apiId + } return li < ri } - let ld = lhs.localizedDetails - let rd = rhs.localizedDetails - if ld != rd { - return ld < rd - } - return lhs.apiId < rhs.apiId + return ld < rd } } diff --git a/Passepartout/App/Intents/IntentDispatcher.swift b/Passepartout/App/Intents/IntentDispatcher.swift index 76041110..bf364dda 100644 --- a/Passepartout/App/Intents/IntentDispatcher.swift +++ b/Passepartout/App/Intents/IntentDispatcher.swift @@ -48,7 +48,7 @@ class IntentDispatcher { intent.profileId = header.id.uuidString intent.providerFullName = providerFullName intent.serverId = server.id - intent.serverName = server.localizedDescription + intent.serverName = server.localizedLongDescription return intent } diff --git a/Passepartout/App/Mac/Models/DefaultLightProviderManager.swift b/Passepartout/App/Mac/Models/DefaultLightProviderManager.swift index ddf49ff4..a6003c56 100644 --- a/Passepartout/App/Mac/Models/DefaultLightProviderManager.swift +++ b/Passepartout/App/Mac/Models/DefaultLightProviderManager.swift @@ -69,7 +69,7 @@ class DefaultLightProviderServer: LightProviderServer { let serverId: String init(_ server: ProviderServer) { - description = server.localizedDescription + description = server.localizedShortDescriptionWithDefault categoryName = server.categoryName locationId = server.locationId serverId = server.id diff --git a/Passepartout/App/Views/ProviderLocationView.swift b/Passepartout/App/Views/ProviderLocationView.swift index c613fd1c..59956f5c 100644 --- a/Passepartout/App/Views/ProviderLocationView.swift +++ b/Passepartout/App/Views/ProviderLocationView.swift @@ -253,10 +253,10 @@ extension ProviderLocationView { HStack { themeAssetsCountryImage(location.countryCode).asAssetImage VStack { - if let singleServer = location.onlyServer, let _ = singleServer.details { + if let singleServer = location.onlyServer, let _ = singleServer.localizedShortDescription { Text(location.localizedCountry) .frame(maxWidth: .infinity, alignment: .leading) - Text(singleServer.localizedDetails.uppercased()) + Text(singleServer.localizedShortDescription ?? "") .frame(maxWidth: .infinity, alignment: .leading) } else { Text(location.localizedCountry) @@ -284,7 +284,7 @@ extension ProviderLocationView { ScrollViewReader { scrollProxy in List { ForEach(servers) { server in - Button(server.localizedDetailsWithDefault) { + Button(server.localizedShortDescriptionWithDefault) { selectedServer = server }.withTrailingCheckmark(when: server.id == selectedServer?.id) } diff --git a/Passepartout/AppShared/L10n/Providers+L10n.swift b/Passepartout/AppShared/L10n/Providers+L10n.swift index faf330da..59118a84 100644 --- a/Passepartout/AppShared/L10n/Providers+L10n.swift +++ b/Passepartout/AppShared/L10n/Providers+L10n.swift @@ -70,21 +70,36 @@ extension ProviderServer { countryCode.localizedAsCountryCode } - var localizedDescription: String { + var localizedShortDescription: String? { + var comps = localizedName.map { [$0] } ?? [] + if let serverIndex = serverIndex { + comps.append("#\(serverIndex)") + } + guard !comps.isEmpty else { + return nil + } + var str = comps.joined(separator: " ") + if let tags = tags { + let suffix = tags.map { $0.uppercased() }.joined(separator: ",") + str = "\(str) (\(suffix))" + } + guard !str.isEmpty else { + return nil + } + return str + } + + var localizedShortDescriptionWithDefault: String { + localizedShortDescription ?? "\(L10n.Global.Strings.default) [\(apiId)]" + } + + var localizedLongDescription: String { var comps: [String] = [localizedCountry] - details.map { + localizedShortDescription.map { comps.append($0) } return comps.joined(separator: " - ") } - - var localizedDetails: String { - details ?? "" - } - - var localizedDetailsWithDefault: String { - details ?? "\(L10n.Global.Strings.default) [\(apiId)]" - } } extension ProviderServer.Preset { diff --git a/PassepartoutLibrary/Sources/PassepartoutCore/Models/ProviderServer.swift b/PassepartoutLibrary/Sources/PassepartoutCore/Models/ProviderServer.swift index 9825549f..1d71481e 100644 --- a/PassepartoutLibrary/Sources/PassepartoutCore/Models/ProviderServer.swift +++ b/PassepartoutLibrary/Sources/PassepartoutCore/Models/ProviderServer.swift @@ -59,9 +59,11 @@ public struct ProviderServer: Identifiable { public let extraCountryCodes: [String]? + public let localizedName: String? + public let serverIndex: Int? - public let details: String? + public let tags: [String]? public let hostname: String? @@ -71,15 +73,16 @@ public struct ProviderServer: Identifiable { public private(set) var presets: [Preset]? - public init(providerMetadata: ProviderMetadata, id: String, apiId: String, categoryName: String, countryCode: String, extraCountryCodes: [String]?, serverIndex: Int?, details: String?, hostname: String?, ipAddresses: [String], presetIds: [String]) { + public init(providerMetadata: ProviderMetadata, id: String, apiId: String, categoryName: String, countryCode: String, extraCountryCodes: [String]?, localizedName: String?, serverIndex: Int?, tags: [String]?, hostname: String?, ipAddresses: [String], presetIds: [String]) { self.providerMetadata = providerMetadata self.id = id self.apiId = apiId self.categoryName = categoryName self.countryCode = countryCode self.extraCountryCodes = extraCountryCodes + self.localizedName = localizedName self.serverIndex = serverIndex - self.details = details + self.tags = tags self.hostname = hostname self.ipAddresses = ipAddresses self.presetIds = presetIds diff --git a/PassepartoutLibrary/Sources/PassepartoutProviders/Repositories/ServerMapper.swift b/PassepartoutLibrary/Sources/PassepartoutProviders/Repositories/ServerMapper.swift index ae2b5d9c..0dfed636 100644 --- a/PassepartoutLibrary/Sources/PassepartoutProviders/Repositories/ServerMapper.swift +++ b/PassepartoutLibrary/Sources/PassepartoutProviders/Repositories/ServerMapper.swift @@ -95,8 +95,9 @@ struct ServerMapper: DTOMapper, ModelMapper { categoryName: categoryName, countryCode: countryCode, extraCountryCodes: dto.decodedExtraCountryCodes, + localizedName: dto.localizedName, serverIndex: dto.serverIndex != 0 ? Int(dto.serverIndex) : nil, - details: dto.details, + tags: dto.decodedTags, hostname: dto.hostname, ipAddresses: dto.decodedIPAddresses, presetIds: supportedPresetIds @@ -164,7 +165,7 @@ private extension CDInfrastructureServer { } private extension CDInfrastructureServer { - var details: String? { + var localizedName: String? { var comps: [String] = [] if let extraCountryCodes = decodedExtraCountryCodes { comps.append(contentsOf: extraCountryCodes.map { @@ -172,24 +173,12 @@ private extension CDInfrastructureServer { }) } if let area = area { -// comps.append(area.uppercased()) comps.append(area.capitalized) } - if serverIndex != 0 { - comps.append("#\(serverIndex)") - } guard !comps.isEmpty else { return nil } - var str = comps.joined(separator: " ") - if let tags = tags { - let suffix = tags.map { $0.uppercased() }.joined(separator: ",") - str = "\(str) (\(suffix))" - } - guard !str.isEmpty else { - return nil - } - return str + return comps.joined(separator: " ") } }