Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PIA-885: Dashboard connect button UI #48

Merged
merged 1 commit into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions PIA VPN-tvOS/Dashboard/CompositionRoot/DashboardFactory.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

import Foundation

class DashboardFactory {

static func makeDashboardView() -> DashboardView {
return DashboardView(
connectionButton: makePIAConnectionButton()
)
}

static func makePIAConnectionButton(size: CGFloat = 160, lineWidth: CGFloat = 6) -> PIAConnectionButton {
return PIAConnectionButton(
size: size,
lineWidth: lineWidth,
viewModel: makePIAConnectionButtonViewModel()
)
}

}

// MARK: Private

extension DashboardFactory {
private static func makePIAConnectionButtonViewModel() -> PIAConnectionButtonViewModel {
return PIAConnectionButtonViewModel(useCase: makeVpnConnectionUseCase())
}

private static func makeVpnConnectionUseCase() -> VpnConnectionUseCaseType {
return VpnConnectionUseCase()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@


import Foundation
import SwiftUI

class PIAConnectionButtonViewModel: ObservableObject {
enum State {
case disconnected
case connecting
case connected
case disconnecting
}

@Published var state: State = .disconnected

private let vpnConnectionUseCase: VpnConnectionUseCaseType

init(useCase: VpnConnectionUseCaseType) {
self.vpnConnectionUseCase = useCase
}

// Inner ring color and outer ring color
var tintColor: (Color, Color) {
switch state {
case .disconnected:
return (.pia_red_dark, .pia_red_dark)
case .connecting, .disconnecting:
return (.pia_yellow_dark, .pia_connect_button_grey)
case .connected:
return (.pia_green, .pia_green)
}
}

var animating: Bool {
state == .connecting ||
state == .disconnecting
}
}

// MARK: Connection

extension PIAConnectionButtonViewModel {

func toggleConnection() {
switch state {
case .disconnected:
connect()
case .connecting:
break
case .connected:
disconnect()
case .disconnecting:
break
}
}

private func connect() {
// TODO: Take the state from the real VpnManager state monitor
state = .connecting

vpnConnectionUseCase.connect()

// TODO: Take the state from the real VpnManager state monitor
DispatchQueue.main.asyncAfter(deadline: .now()+0.2) { [weak self] in
self?.state = .connected
}
}

private func disconnect() {
// TODO: Take the state from the real VpnManager state monitor
state = .disconnecting

vpnConnectionUseCase.disconnect()

// TODO: Take the state from the real VpnManager state monitor
DispatchQueue.main.asyncAfter(deadline: .now()+0.2) { [weak self] in
self?.state = .disconnected
}
}

}

29 changes: 29 additions & 0 deletions PIA VPN-tvOS/Dashboard/UI/DashboardView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

import SwiftUI

struct DashboardView: View {
let viewWidth = UIScreen.main.bounds.width
let viewHeight = UIScreen.main.bounds.height

let connectionButton: PIAConnectionButton

var body: some View {
VStack {
VStack(spacing: 20) {
connectionButton
.padding()
}
.frame(maxWidth: (viewWidth/2))
.padding()

}
.frame(width: viewWidth, height: viewHeight)
.background(Color.app_background)


}
}

#Preview {
DashboardView(connectionButton: DashboardFactory.makePIAConnectionButton())
}
49 changes: 49 additions & 0 deletions PIA VPN-tvOS/Dashboard/UI/PIAConnectionButton.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@


import SwiftUI

struct PIAConnectionButton: View {
var size: CGFloat = 160
var lineWidth: CGFloat = 6

@ObservedObject var viewModel:PIAConnectionButtonViewModel

var body: some View {
Button {
viewModel.toggleConnection()
} label: {
ZStack {
connectingRing(for: viewModel.tintColor.0)
.frame(width: size)
.opacity(viewModel.animating ? 1 : 0)
.animation(Animation
.easeOut(duration: 1)
.repeat(while: viewModel.animating), value: viewModel.animating)
Circle()
.stroke(style: StrokeStyle(lineWidth: lineWidth))
.foregroundStyle(viewModel.animating ? .tertiary : .primary)
.foregroundColor(viewModel.tintColor.1)
.frame(width: size)

Image("vpn-button")
.resizable()
.renderingMode(.template)
.foregroundColor(viewModel.tintColor.0)
.frame(width: (size-100), height: (size-100))
}

}
.buttonStyle(.card)
.buttonBorderShape(ButtonBorderShape.capsule)

}


func connectingRing(for color: Color) -> some View {
Circle()
.trim(from: viewModel.animating ? 0 : 1, to: viewModel.animating ? 1.5 : 1)
.stroke(color.gradient,
style: StrokeStyle(lineWidth: lineWidth, lineCap: .square))
.rotationEffect(.degrees(-95))
}
}
20 changes: 20 additions & 0 deletions PIA VPN-tvOS/Dashboard/UseCases/VpnConnectionUseCase.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

import Foundation

protocol VpnConnectionUseCaseType {
func connect()
func disconnect()
}

class VpnConnectionUseCase: VpnConnectionUseCaseType {

func connect() {
// TODO: Implement
}

func disconnect() {
// TODO: Implement
}


}
5 changes: 5 additions & 0 deletions PIA VPN-tvOS/PIA VPN-tvOS.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>
1 change: 1 addition & 0 deletions PIA VPN-tvOS/PIA_VPN_tvOSApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct PIA_VPN_tvOSApp: App {
var body: some Scene {
WindowGroup {
LoginFactory.makeLoginView()
// DashboardFactory.makeDashboardView()
}
}
}
6 changes: 6 additions & 0 deletions PIA VPN-tvOS/Shared/UI/Colors.xcassets/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"platform" : "ios",
"reference" : "systemGray5Color"
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"colors" : [
{
"color" : {
"platform" : "ios",
"reference" : "opaqueSeparatorColor"
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"platform" : "ios",
"reference" : "systemGray3Color"
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.353",
"green" : "0.874",
"red" : "0.365"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.286",
"green" : "0.714",
"red" : "0.298"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.039",
"green" : "0.474",
"red" : "0.012"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.345",
"green" : "0.267",
"red" : "0.949"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Loading