1
1
import SwiftUI
2
2
3
- struct VPNMenu : View {
4
- @State private var isVPNOn : Bool = false
5
- let workspaces : [ WorkspaceRowContents ]
3
+ struct VPNMenu < Conn : CoderVPN > : View {
4
+ @ObservedObject var vpnService : Conn
5
+
6
6
var body : some View {
7
7
// Main stack
8
8
VStack ( alignment: . leading) {
9
9
// CoderVPN Stack
10
10
VStack ( alignment: . leading, spacing: 10 ) {
11
11
HStack {
12
- Toggle ( isOn: self . $isVPNOn) {
12
+ Toggle ( isOn: Binding (
13
+ get: { self . vpnService. state == . connected || self . vpnService. state == . connecting } ,
14
+ set: { isOn in Task {
15
+ if isOn { await self . vpnService. start ( ) } else { await self . vpnService. stop ( ) }
16
+ }
17
+ }
18
+ ) ) {
13
19
Text ( " CoderVPN " )
14
20
. frame ( maxWidth: . infinity, alignment: . leading)
15
21
} . toggleStyle ( . switch)
22
+ . disabled ( self . vpnService. state == . connecting || self . vpnService. state == . disconnecting)
16
23
}
17
24
Divider ( )
18
- Text ( " Workspaces " )
25
+ Text ( " Workspace Agents " )
19
26
. font ( . headline)
20
27
. foregroundColor ( . gray)
21
- if !isVPNOn {
22
- Text ( " Enable CoderVPN to see workspaces " ) . font ( . body) . foregroundColor ( . gray)
28
+ if self . vpnService. state == . disabled {
29
+ Text ( " Enable CoderVPN to see agents " ) . font ( . body) . foregroundColor ( . gray)
30
+ } else if self . vpnService. state == . connecting || self . vpnService. state == . disconnecting {
31
+ HStack {
32
+ Spacer ( )
33
+ ProgressView (
34
+ self . vpnService. state == . connecting ? " Starting CoderVPN... " : " Stopping CoderVPN... "
35
+ ) . padding ( )
36
+ Spacer ( )
37
+ }
23
38
}
24
39
} . padding ( [ . horizontal, . top] , 15 )
25
- if isVPNOn {
26
- ForEach ( workspaces ) { workspace in
27
- WorkspaceRowView ( workspace: workspace) . padding ( . horizontal, 5 )
40
+ if self . vpnService . state == . connected {
41
+ ForEach ( self . vpnService . data ) { workspace in
42
+ AgentRowView ( workspace: workspace) . padding ( . horizontal, 5 )
28
43
}
29
44
}
30
45
// Trailing stack
@@ -33,32 +48,39 @@ struct VPNMenu: View {
33
48
RowButtonView {
34
49
Text ( " Create workspace " )
35
50
EmptyView ( )
51
+ } action: {
52
+ // TODO
36
53
}
37
54
Divider ( ) . padding ( [ . horizontal] , 10 ) . padding ( . vertical, 4 )
38
55
RowButtonView {
39
56
Text ( " About " )
57
+ } action: {
58
+ // TODO
40
59
}
41
60
RowButtonView {
42
61
Text ( " Preferences " )
62
+ } action: {
63
+ // TODO
43
64
}
44
65
RowButtonView {
45
66
Text ( " Sign out " )
67
+ } action: {
68
+ // TODO
46
69
}
47
70
} . padding ( [ . horizontal, . bottom] , 5 )
48
71
} . padding ( . bottom, 5 )
49
-
50
72
}
51
73
}
52
74
53
- struct WorkspaceRowContents : Identifiable {
54
- let id = UUID ( )
75
+ struct AgentRow : Identifiable {
76
+ let id : UUID
55
77
let name : String
56
78
let status : Color
57
79
let copyableDNS : String
58
80
}
59
81
60
- struct WorkspaceRowView : View {
61
- let workspace : WorkspaceRowContents
82
+ struct AgentRowView : View {
83
+ let workspace : AgentRow
62
84
@State private var nameIsSelected : Bool = false
63
85
@State private var copyIsSelected : Bool = false
64
86
@@ -117,9 +139,11 @@ struct WorkspaceRowView: View {
117
139
struct RowButtonView < Label: View > : View {
118
140
@State private var isSelected : Bool = false
119
141
@ViewBuilder var label : ( ) -> Label
142
+ var action : ( ) -> Void
143
+
120
144
var body : some View {
121
145
Button {
122
- // TODO: Action
146
+ action ( )
123
147
} label: {
124
148
HStack ( spacing: 0 ) {
125
149
label ( )
@@ -137,11 +161,5 @@ struct RowButtonView<Label: View>: View {
137
161
}
138
162
139
163
#Preview {
140
- VPNMenu ( workspaces: [
141
- WorkspaceRowContents ( name: " dogfood2 " , status: . red, copyableDNS: " asdf.coder " ) ,
142
- WorkspaceRowContents ( name: " testing-a-very-long-name " , status: . green, copyableDNS: " asdf.coder " ) ,
143
- WorkspaceRowContents ( name: " opensrc " , status: . yellow, copyableDNS: " asdf.coder " ) ,
144
- WorkspaceRowContents ( name: " gvisor " , status: . gray, copyableDNS: " asdf.coder " ) ,
145
- WorkspaceRowContents ( name: " example " , status: . gray, copyableDNS: " asdf.coder " )
146
- ] ) . frame ( width: 256 )
164
+ VPNMenu ( vpnService: PreviewVPN ( ) ) . frame ( width: 256 )
147
165
}
0 commit comments