11import SwiftUI
22
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+
66 var body : some View {
77 // Main stack
88 VStack ( alignment: . leading) {
99 // CoderVPN Stack
1010 VStack ( alignment: . leading, spacing: 10 ) {
1111 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+ ) ) {
1319 Text ( " CoderVPN " )
1420 . frame ( maxWidth: . infinity, alignment: . leading)
1521 } . toggleStyle ( . switch)
22+ . disabled ( self . vpnService. state == . connecting || self . vpnService. state == . disconnecting)
1623 }
1724 Divider ( )
18- Text ( " Workspaces " )
25+ Text ( " Workspace Agents " )
1926 . font ( . headline)
2027 . 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+ }
2338 }
2439 } . 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 )
2843 }
2944 }
3045 // Trailing stack
@@ -33,32 +48,39 @@ struct VPNMenu: View {
3348 RowButtonView {
3449 Text ( " Create workspace " )
3550 EmptyView ( )
51+ } action: {
52+ // TODO
3653 }
3754 Divider ( ) . padding ( [ . horizontal] , 10 ) . padding ( . vertical, 4 )
3855 RowButtonView {
3956 Text ( " About " )
57+ } action: {
58+ // TODO
4059 }
4160 RowButtonView {
4261 Text ( " Preferences " )
62+ } action: {
63+ // TODO
4364 }
4465 RowButtonView {
4566 Text ( " Sign out " )
67+ } action: {
68+ // TODO
4669 }
4770 } . padding ( [ . horizontal, . bottom] , 5 )
4871 } . padding ( . bottom, 5 )
49-
5072 }
5173}
5274
53- struct WorkspaceRowContents : Identifiable {
54- let id = UUID ( )
75+ struct AgentRow : Identifiable {
76+ let id : UUID
5577 let name : String
5678 let status : Color
5779 let copyableDNS : String
5880}
5981
60- struct WorkspaceRowView : View {
61- let workspace : WorkspaceRowContents
82+ struct AgentRowView : View {
83+ let workspace : AgentRow
6284 @State private var nameIsSelected : Bool = false
6385 @State private var copyIsSelected : Bool = false
6486
@@ -117,9 +139,11 @@ struct WorkspaceRowView: View {
117139struct RowButtonView < Label: View > : View {
118140 @State private var isSelected : Bool = false
119141 @ViewBuilder var label : ( ) -> Label
142+ var action : ( ) -> Void
143+
120144 var body : some View {
121145 Button {
122- // TODO: Action
146+ action ( )
123147 } label: {
124148 HStack ( spacing: 0 ) {
125149 label ( )
@@ -137,11 +161,5 @@ struct RowButtonView<Label: View>: View {
137161}
138162
139163#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 )
147165}
0 commit comments