Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite9ddfbc

Browse files
committed
codervpn abstraction
1 parente8de69e commite9ddfbc

File tree

4 files changed

+103
-30
lines changed

4 files changed

+103
-30
lines changed

‎Desktop/CoderVPN.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import SwiftUI
2+
3+
protocolCoderVPN:ObservableObject{
4+
varstate:CoderVPNState{get}
5+
vardata:[AgentRow]{get}
6+
func start()async
7+
func stop()async
8+
}
9+
10+
enumCoderVPNState:Equatable{
11+
case disabled
12+
case connecting
13+
case disconnecting
14+
case connected
15+
case failed(String)
16+
}

‎Desktop/DesktopApp.swift

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,7 @@ import SwiftUI
44
structDesktopApp:App{
55
varbody:someScene{
66
MenuBarExtra{
7-
VPNMenu(workspaces:[
8-
WorkspaceRowContents(name:"dogfood2", status:.red, copyableDNS:"asdf.coder"),
9-
WorkspaceRowContents(name:"testing-a-very-long-name", status:.green, copyableDNS:"asdf.coder"),
10-
WorkspaceRowContents(name:"opensrc", status:.yellow, copyableDNS:"asdf.coder"),
11-
WorkspaceRowContents(name:"gvisor", status:.gray, copyableDNS:"asdf.coder"),
12-
WorkspaceRowContents(name:"example", status:.gray, copyableDNS:"asdf.coder")
13-
]).frame(width:256)
7+
VPNMenu(vpnService:PreviewVPN()).frame(width:256)
148
} label:{
159
letimage:NSImage={
1610
letratio= $0.size.height/ $0.size.width
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import SwiftUI
2+
3+
classPreviewVPN:Desktop.CoderVPN{
4+
@Publishedvarstate:Desktop.CoderVPNState=.disabled
5+
@Publishedvardata:[Desktop.AgentRow]=[
6+
AgentRow(id:UUID(), name:"dogfood2", status:.red, copyableDNS:"asdf.coder"),
7+
AgentRow(id:UUID(), name:"testing-a-very-long-name", status:.green, copyableDNS:"asdf.coder"),
8+
AgentRow(id:UUID(), name:"opensrc", status:.yellow, copyableDNS:"asdf.coder"),
9+
AgentRow(id:UUID(), name:"gvisor", status:.gray, copyableDNS:"asdf.coder"),
10+
AgentRow(id:UUID(), name:"example", status:.gray, copyableDNS:"asdf.coder")
11+
]
12+
func start()async{
13+
awaitMainActor.run{
14+
state=.connecting
15+
}
16+
do{
17+
tryawaitTask.sleep(nanoseconds:1_000_000_000)
18+
}catch{
19+
awaitMainActor.run{
20+
state=.failed("Timed out starting CoderVPN")
21+
}
22+
return
23+
}
24+
awaitMainActor.run{
25+
state=.connected
26+
}
27+
}
28+
29+
func stop()async{
30+
awaitMainActor.run{
31+
state=.disconnecting
32+
}
33+
do{
34+
tryawaitTask.sleep(nanoseconds:1_000_000_000) // Simulate network delay
35+
}catch{
36+
awaitMainActor.run{
37+
state=.failed("Timed out stopping CoderVPN")
38+
}
39+
return
40+
}
41+
awaitMainActor.run{
42+
state=.disabled
43+
}
44+
}
45+
}

‎Desktop/VPNMenu.swift

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,45 @@
11
import SwiftUI
22

3-
structVPNMenu:View{
4-
@StateprivatevarisVPNOn:Bool=false
5-
letworkspaces:[WorkspaceRowContents]
3+
structVPNMenu<Conn:CoderVPN>:View{
4+
@ObservedObjectvarvpnService:Conn
5+
66
varbody:someView{
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:{ isOninTask{
15+
if isOn{awaitself.vpnService.start()}else{awaitself.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+
ifself.vpnService.state==.disabled{
29+
Text("Enable CoderVPN to see agents").font(.body).foregroundColor(.gray)
30+
}elseifself.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-
ifisVPNOn{
26-
ForEach(workspaces){ workspacein
27-
WorkspaceRowView(workspace: workspace).padding(.horizontal,5)
40+
ifself.vpnService.state==.connected{
41+
ForEach(self.vpnService.data){ workspacein
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-
structWorkspaceRowContents:Identifiable{
54-
letid=UUID()
75+
structAgentRow:Identifiable{
76+
letid:UUID
5577
letname:String
5678
letstatus:Color
5779
letcopyableDNS:String
5880
}
5981

60-
structWorkspaceRowView:View{
61-
letworkspace:WorkspaceRowContents
82+
structAgentRowView:View{
83+
letworkspace:AgentRow
6284
@StateprivatevarnameIsSelected:Bool=false
6385
@StateprivatevarcopyIsSelected:Bool=false
6486

@@ -117,9 +139,11 @@ struct WorkspaceRowView: View {
117139
structRowButtonView<Label:View>:View{
118140
@StateprivatevarisSelected:Bool=false
119141
@ViewBuildervarlabel:()->Label
142+
varaction:()->Void
143+
120144
varbody:someView{
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

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp