Commit 625d5ab8 authored by Jose Blaya's avatar Jose Blaya
Browse files

Filter regions by name, latency or favorite

parent 539ce629
......@@ -175,6 +175,8 @@
DDD271DF21D616AA00B6D20F /* Server+Favorite.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD271DD21D616AA00B6D20F /* Server+Favorite.swift */; };
DDD271E121D6262100B6D20F /* PropertyStoring.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD271E021D6262100B6D20F /* PropertyStoring.swift */; };
DDD271E221D6262100B6D20F /* PropertyStoring.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD271E021D6262100B6D20F /* PropertyStoring.swift */; };
DDD271F021D6718F00B6D20F /* RegionFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD271EF21D6718F00B6D20F /* RegionFilter.swift */; };
DDD271F121D6718F00B6D20F /* RegionFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD271EF21D6718F00B6D20F /* RegionFilter.swift */; };
FE61F5CECAD02C55C725A488 /* Pods_PIA_VPN_Tunnel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E770360A2D0093A53075E293 /* Pods_PIA_VPN_Tunnel.framework */; };
/* End PBXBuildFile section */
......@@ -426,6 +428,7 @@
DDC8124E21761B0B00CB290C /* SwiftGen+ScenesStoryboards.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SwiftGen+ScenesStoryboards.swift"; sourceTree = "<group>"; };
DDD271DD21D616AA00B6D20F /* Server+Favorite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Server+Favorite.swift"; sourceTree = "<group>"; };
DDD271E021D6262100B6D20F /* PropertyStoring.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PropertyStoring.swift; sourceTree = "<group>"; };
DDD271EF21D6718F00B6D20F /* RegionFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegionFilter.swift; sourceTree = "<group>"; };
E770360A2D0093A53075E293 /* Pods_PIA_VPN_Tunnel.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PIA_VPN_Tunnel.framework; sourceTree = BUILT_PRODUCTS_DIR; };
EDFACF2A7A2C3C206153EE1F /* Pods-PIA VPN dev.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PIA VPN dev.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PIA VPN dev/Pods-PIA VPN dev.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
......@@ -600,6 +603,7 @@
0EB0A84B204F0CE2008BCF1D /* DataCounter.swift */,
0EFDC1D91FE4640C007C0B9B /* DNSResolver.swift */,
0EFDC1D61FE46177007C0B9B /* SensitiveOperation.swift */,
DDD271EF21D6718F00B6D20F /* RegionFilter.swift */,
);
name = Utils;
sourceTree = "<group>";
......@@ -1220,12 +1224,14 @@
"${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework",
"${BUILT_PRODUCTS_DIR}/AlamofireImage/AlamofireImage.framework",
"${BUILT_PRODUCTS_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework",
"${BUILT_PRODUCTS_DIR}/DynamicBlurView/DynamicBlurView.framework",
"${BUILT_PRODUCTS_DIR}/FXPageControl/FXPageControl.framework",
"${BUILT_PRODUCTS_DIR}/Gloss/Gloss.framework",
"${BUILT_PRODUCTS_DIR}/MBProgressHUD/MBProgressHUD.framework",
"${PODS_ROOT}/OpenSSL-Apple/frameworks/iPhone/openssl.framework",
"${BUILT_PRODUCTS_DIR}/PIALibrary/PIALibrary.framework",
"${BUILT_PRODUCTS_DIR}/PIATunnel/PIATunnel.framework",
"${BUILT_PRODUCTS_DIR}/PopupDialog/PopupDialog.framework",
"${BUILT_PRODUCTS_DIR}/QuickLayout/QuickLayout.framework",
"${BUILT_PRODUCTS_DIR}/ReachabilitySwift/Reachability.framework",
"${BUILT_PRODUCTS_DIR}/SideMenu/SideMenu.framework",
......@@ -1244,12 +1250,14 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AlamofireImage.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DZNEmptyDataSet.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DynamicBlurView.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FXPageControl.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Gloss.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MBProgressHUD.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PIALibrary.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PIATunnel.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PopupDialog.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/QuickLayout.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reachability.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SideMenu.framework",
......@@ -1300,12 +1308,14 @@
"${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework",
"${BUILT_PRODUCTS_DIR}/AlamofireImage/AlamofireImage.framework",
"${BUILT_PRODUCTS_DIR}/DZNEmptyDataSet/DZNEmptyDataSet.framework",
"${BUILT_PRODUCTS_DIR}/DynamicBlurView/DynamicBlurView.framework",
"${BUILT_PRODUCTS_DIR}/FXPageControl/FXPageControl.framework",
"${BUILT_PRODUCTS_DIR}/Gloss/Gloss.framework",
"${BUILT_PRODUCTS_DIR}/MBProgressHUD/MBProgressHUD.framework",
"${PODS_ROOT}/OpenSSL-Apple/frameworks/iPhone/openssl.framework",
"${BUILT_PRODUCTS_DIR}/PIALibrary/PIALibrary.framework",
"${BUILT_PRODUCTS_DIR}/PIATunnel/PIATunnel.framework",
"${BUILT_PRODUCTS_DIR}/PopupDialog/PopupDialog.framework",
"${BUILT_PRODUCTS_DIR}/QuickLayout/QuickLayout.framework",
"${BUILT_PRODUCTS_DIR}/ReachabilitySwift/Reachability.framework",
"${BUILT_PRODUCTS_DIR}/SideMenu/SideMenu.framework",
......@@ -1322,12 +1332,14 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AlamofireImage.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DZNEmptyDataSet.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DynamicBlurView.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FXPageControl.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Gloss.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MBProgressHUD.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PIALibrary.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PIATunnel.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PopupDialog.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/QuickLayout.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reachability.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SideMenu.framework",
......@@ -1474,6 +1486,7 @@
0E9AEA6320683FDF00B6E59A /* AboutComponent.swift in Sources */,
DD74695B217F07AC00B7BD73 /* DNSList.swift in Sources */,
0E9452AF1FDB5F7A00891948 /* PIAPageControl.swift in Sources */,
DDD271F121D6718F00B6D20F /* RegionFilter.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -1561,6 +1574,7 @@
0E9AEA6220683FDF00B6E59A /* AboutComponent.swift in Sources */,
DD74695A217F07AC00B7BD73 /* DNSList.swift in Sources */,
0E9452AE1FDB5F7A00891948 /* PIAPageControl.swift in Sources */,
DDD271F021D6718F00B6D20F /* RegionFilter.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
......@@ -14,6 +14,7 @@ import SwiftyBeaver
private let log = SwiftyBeaver.self
class AppPreferences {
private struct Entries {
static let version = "Version"
......@@ -30,6 +31,8 @@ class AppPreferences {
static let piaSocketType = "PIASocketType"
static let favoriteServerIdentifiers = "FavoriteServerIdentifiers"
static let regionFilter = "RegionFilter"
}
static let shared = AppPreferences()
......@@ -118,6 +121,18 @@ class AppPreferences {
}
}
var regionFilter: RegionFilter {
get {
guard let rawValue = defaults.string(forKey: Entries.regionFilter) else {
return .name
}
return RegionFilter(rawValue: rawValue) ?? .name
}
set {
defaults.set(newValue.rawValue, forKey: Entries.regionFilter)
}
}
private init() {
guard let defaults = UserDefaults(suiteName: AppConstants.appGroup) else {
fatalError("Unable to initialize app preferences")
......@@ -127,6 +142,7 @@ class AppPreferences {
defaults.register(defaults: [
Entries.version: AppPreferences.currentVersion,
Entries.launched: false,
Entries.regionFilter: RegionFilter.name.rawValue,
Entries.favoriteServerIdentifiers: [],
Entries.didAskToEnableNotifications: false,
Entries.themeCode: ThemeCode.light.rawValue
......
{
"images" : [
{
"idiom" : "universal",
"filename" : "group92.pdf"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
......@@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "universal",
"filename" : "group4Copy2.pdf"
"filename" : "15IllustrationNoResultDarkCopy2.pdf"
}
],
"info" : {
......
......@@ -2,7 +2,7 @@
"images" : [
{
"idiom" : "universal",
"filename" : "group2Copy.pdf"
"filename" : "15IllustrationNoResultLightCopy2.pdf"
}
],
"info" : {
......
//
// RegionFilter.swift
// PIA VPN
//
// Created by Jose Antonio Blaya Garcia on 28/12/2018.
// Copyright © 2018 London Trust Media. All rights reserved.
//
import Foundation
public enum RegionFilter: String {
case name
case latency
case favorite
}
......@@ -9,6 +9,7 @@
import UIKit
import PIALibrary
import DZNEmptyDataSet
import PopupDialog
class RegionsViewController: AutolayoutViewController {
private struct Cells {
......@@ -40,6 +41,7 @@ class RegionsViewController: AutolayoutViewController {
}
self.servers = servers
filterServers()
selectedServer = Client.preferences.displayedServer
......@@ -47,11 +49,45 @@ class RegionsViewController: AutolayoutViewController {
NotificationCenter.default.addObserver(self, selector: #selector(viewHasRotated), name: .UIDeviceOrientationDidChange, object: nil)
setupSearchBarController()
stylePopupDialog()
tableView.emptyDataSetSource = self
tableView.emptyDataSetDelegate = self
}
private func setupRightBarButton() {
navigationItem.rightBarButtonItem = UIBarButtonItem(
image: Asset.Piax.Global.iconFilter.image,
style: .plain,
target: self,
action: #selector(showFilter(_:))
)
navigationItem.rightBarButtonItem?.accessibilityLabel = L10n.Region.Accessibility.filter
}
private func stylePopupDialog() {
let dialogAppearance = PopupDialogDefaultView.appearance()
dialogAppearance.backgroundColor = Theme.current.palette.appearance == .dark ? UIColor.piaGrey6 : .white
dialogAppearance.titleFont = TextStyle.textStyle12.font!
dialogAppearance.titleColor = Theme.current.palette.appearance == .dark ? .white : TextStyle.textStyle12.color
let containerAppearance = PopupDialogContainerView.appearance()
containerAppearance.cornerRadius = 0
containerAppearance.shadowEnabled = false
let overlayAppearance = PopupDialogOverlayView.appearance()
overlayAppearance.color = .black
overlayAppearance.blurEnabled = false
overlayAppearance.liveBlurEnabled = false
overlayAppearance.opacity = 0.5
let buttonAppearance = DefaultButton.appearance()
buttonAppearance.titleFont = TextStyle.textStyle21.font!
buttonAppearance.titleColor = TextStyle.textStyle21.color
buttonAppearance.buttonColor = Theme.current.palette.appearance == .dark ? UIColor.piaGrey6 : .white
buttonAppearance.separatorColor = Theme.current.palette.appearance == .dark ? UIColor.piaGrey10 : UIColor.piaGrey1
}
private func setupSearchBarController() {
searchController.searchResultsUpdater = self
if #available(iOS 9.1, *) {
......@@ -64,8 +100,10 @@ class RegionsViewController: AutolayoutViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
styleNavigationBarWithTitle(L10n.Menu.Item.region)
setupRightBarButton()
let selectedRow = servers.index { (server) -> Bool in
return (server.identifier == selectedServer.identifier)
}
......@@ -77,6 +115,53 @@ class RegionsViewController: AutolayoutViewController {
}
// MARK: Actions
@objc private func showFilter(_ sender: Any?) {
let popup = PopupDialog(title: L10n.Region.Filter.sortby.uppercased(),
message: nil)
let buttonName = DefaultButton(title: L10n.Region.Filter.name.uppercased(), dismissOnTap: true) {
AppPreferences.shared.regionFilter = .name
self.filterServers()
}
let buttonLatency = DefaultButton(title: L10n.Region.Filter.latency.uppercased(), dismissOnTap: true) {
AppPreferences.shared.regionFilter = .latency
self.filterServers()
}
let buttonFavorites = DefaultButton(title: L10n.Region.Filter.favorites.uppercased(), dismissOnTap: true) {
AppPreferences.shared.regionFilter = .favorite
self.filterServers()
}
switch AppPreferences.shared.regionFilter {
case .name:
buttonName.titleColor = UIColor.piaGreenDark20
case .latency:
buttonLatency.titleColor = UIColor.piaGreenDark20
default:
buttonFavorites.titleColor = UIColor.piaGreenDark20
}
popup.addButtons([buttonName, buttonLatency, buttonFavorites])
self.present(popup, animated: true, completion: nil)
}
private func filterServers() {
self.servers = servers.filter({ !$0.isAutomatic })
switch AppPreferences.shared.regionFilter {
case .name:
self.servers = self.servers.sorted(by: { $0.name < $1.name })
case .latency:
self.servers = self.servers.sorted(by: { $0.pingTime ?? 0 < $1.pingTime ?? 0 })
default:
self.servers = self.servers.sorted(by: { $0.isFavorite && !$1.isFavorite })
}
tableView.reloadData()
self.servers.insert(Server.automatic, at: 0)
tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
}
@objc private func viewHasRotated() {
styleNavigationBarWithTitle(L10n.Menu.Item.region)
}
......
......@@ -53,6 +53,7 @@ enum Asset {
static let favoriteUnselectedDark = ImageAsset(name: "favorite-unselected-dark")
static let favoriteUnselected = ImageAsset(name: "favorite-unselected")
static let iconBack = ImageAsset(name: "icon-back")
static let iconFilter = ImageAsset(name: "icon-filter")
static let pagecontrolSelectedDot = ImageAsset(name: "pagecontrol-selected-dot")
static let pagecontrolUnselectedDot = ImageAsset(name: "pagecontrol-unselected-dot")
static let regionSelected = ImageAsset(name: "region-selected")
......@@ -331,6 +332,7 @@ enum Asset {
Piax.Global.favoriteUnselectedDark,
Piax.Global.favoriteUnselected,
Piax.Global.iconBack,
Piax.Global.iconFilter,
Piax.Global.pagecontrolSelectedDot,
Piax.Global.pagecontrolUnselectedDot,
Piax.Global.regionSelected,
......
......@@ -279,6 +279,20 @@ internal enum L10n {
}
internal enum Region {
internal enum Accessibility {
/// Filter
internal static let filter = L10n.tr("Localizable", "region.accessibility.filter")
}
internal enum Filter {
/// Favorites
internal static let favorites = L10n.tr("Localizable", "region.filter.favorites")
/// Latency
internal static let latency = L10n.tr("Localizable", "region.filter.latency")
/// Name
internal static let name = L10n.tr("Localizable", "region.filter.name")
/// Sort regions by
internal static let sortby = L10n.tr("Localizable", "region.filter.sortby")
}
internal enum Search {
/// Search for a region
internal static let placeholder = L10n.tr("Localizable", "region.search.placeholder")
......
......@@ -202,3 +202,8 @@
// REGION
"region.search.placeholder" = "Search for a region";
"region.accessibility.filter" = "Filter";
"region.filter.sortby" = "Sort regions by";
"region.filter.name" = "Name";
"region.filter.latency" = "Latency";
"region.filter.favorites" = "Favorites";
......@@ -65,6 +65,7 @@ def app_pods
pod 'FXPageControl'
pod 'MBProgressHUD'
pod 'DZNEmptyDataSet'
pod 'PopupDialog'
end
def tunnel_pods
......@@ -90,3 +91,13 @@ end
target 'PIA VPN Tunnel' do
tunnel_pods
end
post_install do |installer|
installer.pods_project.targets.each do |target|
if ['PopupDialog'].include? target.name
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '4.2'
end
end
end
end
......@@ -4,6 +4,7 @@ PODS:
- Alamofire (~> 4.7)
- Crashlytics (3.11.1):
- Fabric (~> 1.8.1)
- DynamicBlurView (3.0.1)
- DZNEmptyDataSet (1.8.1)
- Fabric (1.8.1)
- Firebase/Core (5.11.0):
......@@ -94,6 +95,8 @@ PODS:
- PIATunnel/Core (1.1.8):
- OpenSSL-Apple (~> 1.1.0h)
- SwiftyBeaver
- PopupDialog (0.9.1):
- DynamicBlurView (~> 3.0.1)
- QuickLayout (2.0.2)
- ReachabilitySwift (4.3.0)
- SideMenu (3.1.5)
......@@ -117,6 +120,7 @@ DEPENDENCIES:
- PIALibrary/UI (from `/Users/ueshiba/Desktop/PIA/client-library-apple`)
- PIALibrary/VPN (from `/Users/ueshiba/Desktop/PIA/client-library-apple`)
- PIATunnel (from `/Users/ueshiba/Desktop/PIA/tunnel-apple`)
- PopupDialog
- SideMenu (= 3.1.5)
- TPKeyboardAvoiding
......@@ -125,6 +129,7 @@ SPEC REPOS:
- Alamofire
- AlamofireImage
- Crashlytics
- DynamicBlurView
- DZNEmptyDataSet
- Fabric
- Firebase
......@@ -141,6 +146,7 @@ SPEC REPOS:
- MBProgressHUD
- nanopb
- OpenSSL-Apple
- PopupDialog
- QuickLayout
- ReachabilitySwift
- SideMenu
......@@ -158,6 +164,7 @@ SPEC CHECKSUMS:
Alamofire: c7287b6e5d7da964a70935e5db17046b7fde6568
AlamofireImage: 78d67ccbb763d87ba44b21583d2153500a195630
Crashlytics: ca7ab4bc304aa216bdc2e4c1a96389ee77252203
DynamicBlurView: b1df5415f9bd31897549e5d7077e5ec120a4d636
DZNEmptyDataSet: 9525833b9e68ac21c30253e1d3d7076cc828eaa7
Fabric: 43ed7bac010f588f63ee23ab1a0276b296db5e17
Firebase: b48f9e653da971ecce5b8c749684bc8bb2d26bd3
......@@ -176,6 +183,7 @@ SPEC CHECKSUMS:
OpenSSL-Apple: cd153d705ef350eb834ae7ff5f21f792b51ed208
PIALibrary: 31ba3f0a1575931be2472d1b9d590f08bd7876be
PIATunnel: fc7e7d0a812c6c98138ac315e7a43008aadd15b2
PopupDialog: 03985b669c29802661c187513bf827340db1ae4d
QuickLayout: a730730b646b231fd4ef7cffaeb1e81fe0e1ca92
ReachabilitySwift: 408477d1b6ed9779dba301953171e017c31241f3
SideMenu: 47dbf9e4d878062d8994aed43f6e4bf6c1fea30b
......@@ -183,6 +191,6 @@ SPEC CHECKSUMS:
SwiftyBeaver: ccfcdf85a04d429f1633f668650b0ce8020bda3a
TPKeyboardAvoiding: cb69d5ddbe90ce0170e4bc2db1e5e41d4a3ad9a4
PODFILE CHECKSUM: 9e29df2214344b5d516bad51a27ea901dccf51fe
PODFILE CHECKSUM: 87fc45c9dcad7b255ea49de23cf784af7b7efa83
COCOAPODS: 1.5.3
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment