Commit 0bf801d1 authored by Jose Blaya's avatar Jose Blaya
Browse files

Usage tile

parent e42eb9ea
This diff is collapsed.
......@@ -25,6 +25,7 @@ class DashboardViewController: AutolayoutViewController {
case quickConnect
case ipTile
case subscription
case usage
var identifier: String {
switch self {
......@@ -32,6 +33,7 @@ class DashboardViewController: AutolayoutViewController {
case .quickConnect: return "QuickConnectTileCell"
case .region: return "RegionTileCell"
case .subscription: return "SubscriptionTileCell"
case .usage: return "UsageTileCell"
}
}
......@@ -41,6 +43,7 @@ class DashboardViewController: AutolayoutViewController {
case .quickConnect: return "QuickConnectTileCollectionViewCell"
case .region: return "RegionTileCollectionViewCell"
case .subscription: return "SubscriptionTileCollectionViewCell"
case .usage: return "UsageTileCollectionViewCell"
}
}
}
......@@ -184,6 +187,9 @@ class DashboardViewController: AutolayoutViewController {
collectionView.register(UINib(nibName: Cells.subscription.className,
bundle: nil),
forCellWithReuseIdentifier: Cells.subscription.identifier)
collectionView.register(UINib(nibName: Cells.usage.className,
bundle: nil),
forCellWithReuseIdentifier: Cells.usage.identifier)
collectionView.backgroundColor = .clear
}
......@@ -239,12 +245,23 @@ class DashboardViewController: AutolayoutViewController {
@IBAction func vpnButtonClicked(_ sender: Any?) {
if !toggleConnection.isOn {
Client.providers.vpnProvider.connect(nil)
Client.providers.vpnProvider.connect({ [weak self] _ in
self?.reloadUsageTileAfter(seconds: 5) //Show some usage after 5 seconds of activity
})
NotificationCenter.default.post(name: .PIAServerHasBeenUpdated,
object: self,
userInfo: nil)
} else {
Client.providers.vpnProvider.disconnect(nil)
Client.providers.vpnProvider.disconnect({ [weak self] _ in
self?.reloadUsageTileAfter(seconds: 1) //Reset the usage statistics after stop the VPN
})
}
Macros.postNotification(.PIAVPNUsageUpdate)
}
private func reloadUsageTileAfter(seconds: TimeInterval) {
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
Macros.postNotification(.PIAVPNUsageUpdate)
}
}
......@@ -320,6 +337,7 @@ class DashboardViewController: AutolayoutViewController {
// MARK: Helpers
@objc private func updateCurrentStatus() {
Macros.postNotification(.PIAVPNUsageUpdate)
updateCurrentStatusWithUserInfo(nil)
}
......@@ -330,8 +348,6 @@ class DashboardViewController: AutolayoutViewController {
@objc private func updateCurrentStatusWithUserInfo(_ userInfo: [AnyHashable: Any]?) {
currentStatus = Client.providers.vpnProvider.vpnStatus
//Theme.current.applyVPNStatus(labelStatus, forStatus: currentStatus)
switch currentStatus {
case .connected:
toggleConnection.isOn = true
......
......@@ -517,6 +517,14 @@ internal enum L10n {
}
}
}
internal enum Usage {
/// Download
internal static let download = L10n.tr("Localizable", "tiles.usage.download")
/// Usage
internal static let title = L10n.tr("Localizable", "tiles.usage.title")
/// Upload
internal static let upload = L10n.tr("Localizable", "tiles.usage.upload")
}
}
internal enum VpnPermission {
......
......@@ -13,7 +13,7 @@ class SubscriptionTileCollectionViewCell: UICollectionViewCell, TileableCell {
var tileType: AvailableTiles = .subscription
typealias Entity = IPTile
typealias Entity = SubscriptionTile
@IBOutlet private weak var tile: Entity!
@IBOutlet private weak var accessoryImageRight: UIImageView!
@IBOutlet private weak var accessoryButtonLeft: UIButton!
......@@ -58,6 +58,6 @@ class SubscriptionTileCollectionViewCell: UICollectionViewCell, TileableCell {
visibleTiles.append(tileType)
Client.providers.tileProvider.visibleTiles = visibleTiles
}
Macros.postNotification(.PIAThemeDidChange)
Macros.postNotification(.PIATilesDidChange)
}
}
//
// UsageTile.swift
// PIA VPN
//
// Created by Jose Antonio Blaya Garcia on 14/01/2019.
// Copyright © 2019 London Trust Media. All rights reserved.
//
import Foundation
import PIALibrary
class UsageTile: UIView, Tileable {
var view: UIView!
var detailSegueIdentifier: String!
var status: TileStatus = .normal
@IBOutlet private weak var usageTitle: UILabel!
@IBOutlet private weak var uploadTitle: UILabel!
@IBOutlet private weak var uploadValue: UILabel!
@IBOutlet private weak var downloadTitle: UILabel!
@IBOutlet private weak var downloadValue: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
self.xibSetup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.xibSetup()
self.setupView()
}
deinit {
NotificationCenter.default.removeObserver(self)
}
private func setupView() {
let nc = NotificationCenter.default
nc.addObserver(self, selector: #selector(viewShouldRestyle), name: .PIAThemeDidChange, object: nil)
nc.addObserver(self, selector: #selector(displayUsageInformation), name: .PIAVPNUsageUpdate, object: nil)
viewShouldRestyle()
self.usageTitle.text = L10n.Tiles.Usage.title.uppercased()
self.uploadTitle.text = L10n.Tiles.Usage.upload
self.downloadTitle.text = L10n.Tiles.Usage.download
displayUsageInformation()
}
@objc private func viewShouldRestyle() {
usageTitle.style(style: TextStyle.textStyle21)
Theme.current.applySettingsCellTitle(uploadValue, appearance: .dark)
Theme.current.applySettingsCellTitle(downloadValue, appearance: .dark)
Theme.current.applySubtitleTileUsage(uploadTitle, appearance: .dark)
Theme.current.applySubtitleTileUsage(downloadTitle, appearance: .dark)
Theme.current.applySolidLightBackground(self)
displayUsageInformation()
}
@objc private func displayUsageInformation() {
Client.providers.vpnProvider.dataUsage { (usage, error) in
var uploaded = Int64(0)
var downloaded = Int64(0)
if error == nil,
let usage = usage {
uploaded = Int64(usage.uploaded)
downloaded = Int64(usage.downloaded)
}
self.uploadValue.text = ByteCountFormatter.string(fromByteCount: uploaded,
countStyle: .file)
self.downloadValue.text = ByteCountFormatter.string(fromByteCount: downloaded,
countStyle: .file)
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="UsageTile" customModule="PIA_VPN" customModuleProvider="target">
<connections>
<outlet property="downloadTitle" destination="0Bg-0g-wy1" id="bEZ-oX-zJe"/>
<outlet property="downloadValue" destination="jve-MQ-JeE" id="RIg-eE-Rbz"/>
<outlet property="uploadTitle" destination="L1A-Sl-HOT" id="6OB-js-sld"/>
<outlet property="uploadValue" destination="z3G-2S-4D8" id="8fY-vS-4Hp"/>
<outlet property="usageTitle" destination="3hN-bp-xD7" id="Rke-Rf-dVT"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="561" height="286"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3hN-bp-xD7">
<rect key="frame" x="25" y="15" width="511" height="40.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="zjp-da-E8E">
<rect key="frame" x="25" y="55.5" width="511" height="215.5"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="TzI-28-dRz">
<rect key="frame" x="0.0" y="0.0" width="255.5" height="215.5"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" alignment="top" translatesAutoresizingMaskIntoConstraints="NO" id="fQh-jM-Clw">
<rect key="frame" x="0.0" y="0.0" width="255.5" height="215.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0Bg-0g-wy1">
<rect key="frame" x="0.0" y="0.0" width="42" height="108"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jve-MQ-JeE">
<rect key="frame" x="0.0" y="108" width="42" height="107.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="fQh-jM-Clw" firstAttribute="top" secondItem="TzI-28-dRz" secondAttribute="top" id="0qt-oo-nKK"/>
<constraint firstAttribute="bottom" secondItem="fQh-jM-Clw" secondAttribute="bottom" id="N1c-C4-v3c"/>
<constraint firstAttribute="trailing" secondItem="fQh-jM-Clw" secondAttribute="trailing" id="P1h-O3-jhy"/>
<constraint firstItem="fQh-jM-Clw" firstAttribute="leading" secondItem="TzI-28-dRz" secondAttribute="leading" id="qdE-gX-2bM"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="GR6-xe-koy">
<rect key="frame" x="255.5" y="0.0" width="255.5" height="215.5"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" alignment="top" translatesAutoresizingMaskIntoConstraints="NO" id="IjI-6a-Lgg">
<rect key="frame" x="0.0" y="0.0" width="255.5" height="215.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="L1A-Sl-HOT">
<rect key="frame" x="0.0" y="0.0" width="42" height="108"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="z3G-2S-4D8">
<rect key="frame" x="0.0" y="108" width="42" height="107.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="IjI-6a-Lgg" secondAttribute="trailing" id="MFY-PL-Cps"/>
<constraint firstAttribute="bottom" secondItem="IjI-6a-Lgg" secondAttribute="bottom" id="UUg-bM-gur"/>
<constraint firstItem="IjI-6a-Lgg" firstAttribute="leading" secondItem="GR6-xe-koy" secondAttribute="leading" id="mRg-kL-IhN"/>
<constraint firstItem="IjI-6a-Lgg" firstAttribute="top" secondItem="GR6-xe-koy" secondAttribute="top" id="t2U-Al-SFT"/>
</constraints>
</view>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="vUN-kp-3ea" firstAttribute="bottom" secondItem="zjp-da-E8E" secondAttribute="bottom" constant="15" id="FgT-qG-dTN"/>
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="3hN-bp-xD7" secondAttribute="trailing" constant="25" id="Phh-Io-xQj"/>
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="zjp-da-E8E" secondAttribute="trailing" constant="25" id="ReX-uS-0qn"/>
<constraint firstItem="3hN-bp-xD7" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="25" id="TL4-uh-OId"/>
<constraint firstItem="3hN-bp-xD7" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="15" id="X6W-iA-1bE"/>
<constraint firstItem="zjp-da-E8E" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="25" id="flD-tt-H2G"/>
<constraint firstItem="zjp-da-E8E" firstAttribute="top" secondItem="3hN-bp-xD7" secondAttribute="bottom" id="qvj-9f-fMI"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
<point key="canvasLocation" x="189.59999999999999" y="-33.283358320839582"/>
</view>
</objects>
</document>
//
// UsageTileCollectionViewCell.swift
// PIA VPN
//
// Created by Jose Antonio Blaya Garcia on 14/01/2019.
// Copyright © 2019 London Trust Media. All rights reserved.
//
import UIKit
import PIALibrary
class UsageTileCollectionViewCell: UICollectionViewCell, TileableCell {
var tileType: AvailableTiles = .usage
typealias Entity = UsageTile
@IBOutlet private weak var tile: Entity!
@IBOutlet private weak var accessoryImageRight: UIImageView!
@IBOutlet private weak var accessoryButtonLeft: UIButton!
@IBOutlet weak var tileLeftConstraint: NSLayoutConstraint!
@IBOutlet weak var tileRightConstraint: NSLayoutConstraint!
func setupCellForStatus(_ status: TileStatus) {
Theme.current.applySolidLightBackground(self)
Theme.current.applySolidLightBackground(self.contentView)
self.accessoryImageRight.image = Theme.current.dragDropImage()
tile.status = status
UIView.animate(withDuration: AppConfiguration.Animations.duration, animations: {
switch status {
case .normal:
self.tileLeftConstraint.constant = 0
self.tileRightConstraint.constant = 0
case .edit:
self.tileLeftConstraint.constant = self.leftConstraintValue
self.tileRightConstraint.constant = self.rightConstraintValue
self.setupVisibilityButton()
}
self.layoutIfNeeded()
})
}
private func setupVisibilityButton() {
if Client.providers.tileProvider.visibleTiles.contains(tileType) {
accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .normal)
accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .highlighted)
} else {
accessoryButtonLeft.setImage(Theme.current.inactiveEyeImage(), for: .normal)
accessoryButtonLeft.setImage(Theme.current.activeEyeImage(), for: .highlighted)
}
}
@IBAction private func changeTileVisibility() {
var visibleTiles = Client.providers.tileProvider.visibleTiles
if Client.providers.tileProvider.visibleTiles.contains(tileType) {
let tiles = visibleTiles.filter { $0 != tileType }
Client.providers.tileProvider.visibleTiles = tiles
} else {
visibleTiles.append(tileType)
Client.providers.tileProvider.visibleTiles = visibleTiles
}
Macros.postNotification(.PIATilesDidChange)
}
}
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="UsageTileCell" id="gTV-IL-0wX" customClass="UsageTileCollectionViewCell" customModule="PIA_VPN" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="335" height="76"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="335" height="76"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="tSn-9h-eq8">
<rect key="frame" x="15" y="27" width="16" height="22"/>
<state key="normal" image="eye-active"/>
<connections>
<action selector="changeTileVisibility" destination="gTV-IL-0wX" eventType="touchUpInside" id="bFk-gl-t55"/>
</connections>
</button>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="open-tile-details" translatesAutoresizingMaskIntoConstraints="NO" id="xNn-mr-ccn">
<rect key="frame" x="308" y="32" width="12" height="12"/>
</imageView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gFR-hf-yjv" customClass="UsageTile" customModule="PIA_VPN" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="335" height="76"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
</subviews>
</view>
<constraints>
<constraint firstAttribute="bottom" secondItem="gFR-hf-yjv" secondAttribute="bottom" id="5OI-fz-ihv"/>
<constraint firstItem="tSn-9h-eq8" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" constant="15" id="6AV-Qw-6jo"/>
<constraint firstItem="gFR-hf-yjv" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="Fpx-6G-lTK"/>
<constraint firstItem="xNn-mr-ccn" firstAttribute="width" secondItem="xNn-mr-ccn" secondAttribute="height" multiplier="1:1" id="LAs-7x-gF6"/>
<constraint firstItem="xNn-mr-ccn" firstAttribute="centerY" secondItem="gTV-IL-0wX" secondAttribute="centerY" id="Snp-bQ-hiv"/>
<constraint firstItem="gFR-hf-yjv" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="eiX-Vy-zrx"/>
<constraint firstAttribute="trailing" secondItem="xNn-mr-ccn" secondAttribute="trailing" constant="15" id="kgv-vf-LYQ"/>
<constraint firstAttribute="trailing" secondItem="gFR-hf-yjv" secondAttribute="trailing" id="n3H-61-9JT"/>
<constraint firstItem="tSn-9h-eq8" firstAttribute="centerY" secondItem="gTV-IL-0wX" secondAttribute="centerY" id="xzl-vE-rBh"/>
</constraints>
<viewLayoutGuide key="safeArea" id="ZTg-uK-7eu"/>
<size key="customSize" width="335" height="76"/>
<connections>
<outlet property="accessoryButtonLeft" destination="tSn-9h-eq8" id="ZOB-Rf-IDp"/>
<outlet property="accessoryImageRight" destination="xNn-mr-ccn" id="Cgi-wa-nZw"/>
<outlet property="tile" destination="gFR-hf-yjv" id="WDd-Kb-3Q0"/>
<outlet property="tileLeftConstraint" destination="eiX-Vy-zrx" id="Peh-Nj-B1j"/>
<outlet property="tileRightConstraint" destination="n3H-61-9JT" id="PBO-ch-2fO"/>
</connections>
<point key="canvasLocation" x="365.60000000000002" y="143.02848575712144"/>
</collectionViewCell>
</objects>
<resources>
<image name="eye-active" width="16" height="16"/>
<image name="open-tile-details" width="12" height="12"/>
</resources>
</document>
......@@ -216,3 +216,6 @@
"tiles.subscription.monthly" = "Monthly";
"tiles.subscription.yearly" = "Yearly";
"tiles.subscription.days.left" = "(%d days left)";
"tiles.usage.title" = "Usage";
"tiles.usage.upload" = "Upload";
"tiles.usage.download" = "Download";
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