@@ -2,24 +2,27 @@ import SwiftUI
22
33struct VPNMenu < VPN: CoderVPN > : View {
44 @ObservedObject var vpnService : VPN
5+ @State var viewAll = false
6+
7+ private let defaultVisibleRows = 5
58
69 var body : some View {
710 // Main stack
8- VStack ( alignment: . leading) {
11+ VStackLayout ( alignment: . leading) {
912 // CoderVPN Stack
1013 VStack ( alignment: . leading, spacing: 10 ) {
1114 HStack {
1215 Toggle ( isOn: Binding (
1316 get: { self . vpnService. state == . connected || self . vpnService. state == . connecting } ,
1417 set: { isOn in Task {
15- if isOn { await self . vpnService. start ( ) } else { await self . vpnService. stop ( ) }
16- }
18+ if isOn { await self . vpnService. start ( ) } else { await self . vpnService. stop ( ) }
19+ }
1720 }
1821 ) ) {
1922 Text ( " CoderVPN " )
2023 . frame ( maxWidth: . infinity, alignment: . leading)
2124 } . toggleStyle ( . switch)
22- . disabled ( self . vpnService. state == . connecting || self . vpnService. state == . disconnecting)
25+ . disabled ( self . vpnService. state == . connecting || self . vpnService. state == . disconnecting)
2326 }
2427 Divider ( )
2528 Text ( " Workspace Agents " )
@@ -35,12 +38,34 @@ struct VPNMenu<VPN: CoderVPN>: View {
3538 ) . padding ( )
3639 Spacer ( )
3740 }
41+ } else if case let . failed( vpnErr) = self . vpnService. state {
42+ Text ( " \( vpnErr. description) " )
43+ . font ( . headline)
44+ . foregroundColor ( . red)
45+ . multilineTextAlignment ( . center)
46+ . fixedSize ( horizontal: false , vertical: true )
47+ . padding ( . horizontal, 15 )
48+ . padding ( . top, 5 )
49+ . frame ( maxWidth: . infinity)
3850 }
3951 } . padding ( [ . horizontal, . top] , 15 )
52+ // Workspaces List
4053 if self . vpnService. state == . connected {
41- ForEach ( self . vpnService. data) { workspace in
54+ let visibleData = viewAll ? vpnService. data : Array ( vpnService. data. prefix ( defaultVisibleRows) )
55+ ForEach ( visibleData) { workspace in
4256 AgentRowView ( workspace: workspace) . padding ( . horizontal, 5 )
4357 }
58+ if vpnService. data. count > defaultVisibleRows {
59+ Button ( action: {
60+ viewAll. toggle ( )
61+ } , label: {
62+ Text ( viewAll ? " Show Less " : " Show All " )
63+ . font ( . headline)
64+ . foregroundColor ( . gray)
65+ . padding ( . horizontal, 15 )
66+ . padding ( . top, 5 )
67+ } ) . buttonStyle ( . plain)
68+ }
4469 }
4570 // Trailing stack
4671 VStack ( alignment: . leading, spacing: 3 ) {
@@ -49,29 +74,29 @@ struct VPNMenu<VPN: CoderVPN>: View {
4974 Text ( " Create workspace " )
5075 EmptyView ( )
5176 } action: {
52- // TODO
77+ // TODO:
5378 }
5479 Divider ( ) . padding ( [ . horizontal] , 10 ) . padding ( . vertical, 4 )
5580 ButtonRowView {
5681 Text ( " About " )
5782 } action: {
58- // TODO
83+ // TODO:
5984 }
6085 ButtonRowView {
6186 Text ( " Preferences " )
6287 } action: {
63- // TODO
88+ // TODO:
6489 }
6590 ButtonRowView {
6691 Text ( " Sign out " )
6792 } action: {
68- // TODO
93+ // TODO:
6994 }
7095 } . padding ( [ . horizontal, . bottom] , 5 )
7196 } . padding ( . bottom, 5 )
7297 }
7398}
7499
75100#Preview {
76- VPNMenu ( vpnService: PreviewVPN ( ) ) . frame ( width: 256 )
101+ VPNMenu ( vpnService: PreviewVPN ( shouldFail : true ) ) . frame ( width: 256 )
77102}
0 commit comments