Fix server description and sorting

- Name (countries, area)
- Index
- Tags

Also use short description in menu (without country prefix).
This commit is contained in:
Davide De Rosa 2022-07-16 16:41:20 +02:00
parent ce280c0826
commit 9458c4f3a3
7 changed files with 61 additions and 42 deletions

View File

@ -69,19 +69,31 @@ extension ProviderServer: Comparable {
lhs.id == rhs.id lhs.id == rhs.id
} }
// "Default" comes first // "Default" comes first (nil localizedName)
// sorts by serverIndex first, see ProtonVPN > Germany (currently "Frankfurt #203" comes before "#3")
public static func <(lhs: Self, rhs: Self) -> Bool { public static func <(lhs: Self, rhs: Self) -> Bool {
if let li = lhs.serverIndex, let ri = rhs.serverIndex { guard let ld = lhs.localizedName else {
return li < ri return true
} }
let ld = lhs.localizedDetails guard let rd = rhs.localizedName else {
let rd = rhs.localizedDetails return false
if ld != rd { }
return ld < rd 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 lhs.apiId < rhs.apiId
} }
return li < ri
}
return ld < rd
}
} }
extension ProviderServer.Preset: Comparable { extension ProviderServer.Preset: Comparable {

View File

@ -48,7 +48,7 @@ class IntentDispatcher {
intent.profileId = header.id.uuidString intent.profileId = header.id.uuidString
intent.providerFullName = providerFullName intent.providerFullName = providerFullName
intent.serverId = server.id intent.serverId = server.id
intent.serverName = server.localizedDescription intent.serverName = server.localizedLongDescription
return intent return intent
} }

View File

@ -69,7 +69,7 @@ class DefaultLightProviderServer: LightProviderServer {
let serverId: String let serverId: String
init(_ server: ProviderServer) { init(_ server: ProviderServer) {
description = server.localizedDescription description = server.localizedShortDescriptionWithDefault
categoryName = server.categoryName categoryName = server.categoryName
locationId = server.locationId locationId = server.locationId
serverId = server.id serverId = server.id

View File

@ -253,10 +253,10 @@ extension ProviderLocationView {
HStack { HStack {
themeAssetsCountryImage(location.countryCode).asAssetImage themeAssetsCountryImage(location.countryCode).asAssetImage
VStack { VStack {
if let singleServer = location.onlyServer, let _ = singleServer.details { if let singleServer = location.onlyServer, let _ = singleServer.localizedShortDescription {
Text(location.localizedCountry) Text(location.localizedCountry)
.frame(maxWidth: .infinity, alignment: .leading) .frame(maxWidth: .infinity, alignment: .leading)
Text(singleServer.localizedDetails.uppercased()) Text(singleServer.localizedShortDescription ?? "")
.frame(maxWidth: .infinity, alignment: .leading) .frame(maxWidth: .infinity, alignment: .leading)
} else { } else {
Text(location.localizedCountry) Text(location.localizedCountry)
@ -284,7 +284,7 @@ extension ProviderLocationView {
ScrollViewReader { scrollProxy in ScrollViewReader { scrollProxy in
List { List {
ForEach(servers) { server in ForEach(servers) { server in
Button(server.localizedDetailsWithDefault) { Button(server.localizedShortDescriptionWithDefault) {
selectedServer = server selectedServer = server
}.withTrailingCheckmark(when: server.id == selectedServer?.id) }.withTrailingCheckmark(when: server.id == selectedServer?.id)
} }

View File

@ -70,21 +70,36 @@ extension ProviderServer {
countryCode.localizedAsCountryCode 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] var comps: [String] = [localizedCountry]
details.map { localizedShortDescription.map {
comps.append($0) comps.append($0)
} }
return comps.joined(separator: " - ") return comps.joined(separator: " - ")
} }
var localizedDetails: String {
details ?? ""
}
var localizedDetailsWithDefault: String {
details ?? "\(L10n.Global.Strings.default) [\(apiId)]"
}
} }
extension ProviderServer.Preset { extension ProviderServer.Preset {

View File

@ -59,9 +59,11 @@ public struct ProviderServer: Identifiable {
public let extraCountryCodes: [String]? public let extraCountryCodes: [String]?
public let localizedName: String?
public let serverIndex: Int? public let serverIndex: Int?
public let details: String? public let tags: [String]?
public let hostname: String? public let hostname: String?
@ -71,15 +73,16 @@ public struct ProviderServer: Identifiable {
public private(set) var presets: [Preset]? 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.providerMetadata = providerMetadata
self.id = id self.id = id
self.apiId = apiId self.apiId = apiId
self.categoryName = categoryName self.categoryName = categoryName
self.countryCode = countryCode self.countryCode = countryCode
self.extraCountryCodes = extraCountryCodes self.extraCountryCodes = extraCountryCodes
self.localizedName = localizedName
self.serverIndex = serverIndex self.serverIndex = serverIndex
self.details = details self.tags = tags
self.hostname = hostname self.hostname = hostname
self.ipAddresses = ipAddresses self.ipAddresses = ipAddresses
self.presetIds = presetIds self.presetIds = presetIds

View File

@ -95,8 +95,9 @@ struct ServerMapper: DTOMapper, ModelMapper {
categoryName: categoryName, categoryName: categoryName,
countryCode: countryCode, countryCode: countryCode,
extraCountryCodes: dto.decodedExtraCountryCodes, extraCountryCodes: dto.decodedExtraCountryCodes,
localizedName: dto.localizedName,
serverIndex: dto.serverIndex != 0 ? Int(dto.serverIndex) : nil, serverIndex: dto.serverIndex != 0 ? Int(dto.serverIndex) : nil,
details: dto.details, tags: dto.decodedTags,
hostname: dto.hostname, hostname: dto.hostname,
ipAddresses: dto.decodedIPAddresses, ipAddresses: dto.decodedIPAddresses,
presetIds: supportedPresetIds presetIds: supportedPresetIds
@ -164,7 +165,7 @@ private extension CDInfrastructureServer {
} }
private extension CDInfrastructureServer { private extension CDInfrastructureServer {
var details: String? { var localizedName: String? {
var comps: [String] = [] var comps: [String] = []
if let extraCountryCodes = decodedExtraCountryCodes { if let extraCountryCodes = decodedExtraCountryCodes {
comps.append(contentsOf: extraCountryCodes.map { comps.append(contentsOf: extraCountryCodes.map {
@ -172,24 +173,12 @@ private extension CDInfrastructureServer {
}) })
} }
if let area = area { if let area = area {
// comps.append(area.uppercased())
comps.append(area.capitalized) comps.append(area.capitalized)
} }
if serverIndex != 0 {
comps.append("#\(serverIndex)")
}
guard !comps.isEmpty else { guard !comps.isEmpty else {
return nil return nil
} }
var str = comps.joined(separator: " ") return 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
} }
} }