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

Commit09bcf7c

Browse files
committed
show less/more + display error
1 parent840df63 commit09bcf7c

File tree

8 files changed

+94
-52
lines changed

8 files changed

+94
-52
lines changed

‎.swiftlint.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
disabled_rules:
2-
-todo
2+
-todo
3+
-trailing_comma

‎Desktop/AgentRow.swift

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

3-
structAgentRow:Identifiable{
3+
structAgentRow:Identifiable,Equatable{
44
letid:UUID
55
letname:String
66
letstatus:Color
@@ -55,11 +55,11 @@ struct AgentRowView: View {
5555
.padding(3)
5656
}.foregroundStyle(copyIsSelected?Color.white:.primary)
5757
.imageScale(.small)
58-
.background(copyIsSelected?Color.accentColor.opacity(0.8):.clear)
59-
.clipShape(.rect(cornerRadius:4))
60-
.onHover{ hoveringin copyIsSelected= hovering}
61-
.buttonStyle(.plain)
62-
.padding(.trailing,5)
58+
.background(copyIsSelected?Color.accentColor.opacity(0.8):.clear)
59+
.clipShape(.rect(cornerRadius:4))
60+
.onHover{ hoveringin copyIsSelected= hovering}
61+
.buttonStyle(.plain)
62+
.padding(.trailing,5)
6363
}
6464
}
6565
}

‎Desktop/CoderVPN.swift

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,20 @@ protocol CoderVPN: ObservableObject {
88
}
99

1010
enumCoderVPNState:Equatable{
11-
case disabled
12-
case connecting
13-
case disconnecting
14-
case connected
15-
case failed(String)
11+
case disabled
12+
case connecting
13+
case disconnecting
14+
case connected
15+
case failed(CoderVPNError)
16+
}
17+
18+
enumCoderVPNError:Error{
19+
case exampleError
20+
21+
vardescription:String{
22+
switchself{
23+
case.exampleError:
24+
return"This is a long error to test the UI with long errors"
25+
}
26+
}
1627
}

‎Desktop/Preview Content/PreviewVPN.swift

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,48 @@ class PreviewVPN: Desktop.CoderVPN {
77
AgentRow(id:UUID(), name:"testing-a-very-long-name", status:.green, copyableDNS:"asdf.coder"),
88
AgentRow(id:UUID(), name:"opensrc", status:.yellow, copyableDNS:"asdf.coder"),
99
AgentRow(id:UUID(), name:"gvisor", status:.gray, copyableDNS:"asdf.coder"),
10-
AgentRow(id:UUID(), name:"example", status:.gray, copyableDNS:"asdf.coder")
10+
AgentRow(id:UUID(), name:"example", status:.gray, copyableDNS:"asdf.coder"),
11+
AgentRow(id:UUID(), name:"dogfood2", status:.red, copyableDNS:"asdf.coder"),
12+
AgentRow(id:UUID(), name:"testing-a-very-long-name", status:.green, copyableDNS:"asdf.coder"),
13+
AgentRow(id:UUID(), name:"opensrc", status:.yellow, copyableDNS:"asdf.coder"),
14+
AgentRow(id:UUID(), name:"gvisor", status:.gray, copyableDNS:"asdf.coder"),
15+
AgentRow(id:UUID(), name:"example", status:.gray, copyableDNS:"asdf.coder"),
1116
]
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-
}
17+
letshouldFail:Bool
2818

29-
func stop()async{
19+
init(shouldFail:Bool=false){
20+
self.shouldFail= shouldFail
21+
}
22+
23+
privatefunc setState(_ newState:Desktop.CoderVPNState)async{
3024
awaitMainActor.run{
31-
state=.disconnecting
25+
self.state=newState
3226
}
27+
}
28+
29+
func start()async{
30+
awaitsetState(.connecting)
3331
do{
34-
tryawaitTask.sleep(nanoseconds:1_000_000_000) // Simulate network delay
32+
tryawaitTask.sleep(nanoseconds:1000000000)
3533
}catch{
36-
awaitMainActor.run{
37-
state=.failed("Timed out stopping CoderVPN")
38-
}
34+
awaitsetState(.failed(.exampleError))
3935
return
4036
}
41-
awaitMainActor.run{
42-
state=.disabled
37+
if shouldFail{
38+
awaitsetState(.failed(.exampleError))
39+
}else{
40+
awaitsetState(.connected)
41+
}
42+
}
43+
44+
func stop()async{
45+
awaitsetState(.disconnecting)
46+
do{
47+
tryawaitTask.sleep(nanoseconds:1000000000) // Simulate network delay
48+
}catch{
49+
awaitsetState(.failed(.exampleError))
50+
return
4351
}
52+
awaitsetState(.disabled)
4453
}
4554
}

‎Desktop/VPNMenu.swift

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,27 @@ import SwiftUI
22

33
structVPNMenu<VPN:CoderVPN>:View{
44
@ObservedObjectvarvpnService:VPN
5+
@StatevarviewAll=false
6+
7+
privateletdefaultVisibleRows=5
58

69
varbody:someView{
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:{ isOninTask{
15-
if isOn{awaitself.vpnService.start()}else{awaitself.vpnService.stop()}
16-
}
18+
if isOn{awaitself.vpnService.start()}else{awaitself.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+
}elseif caselet.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
ifself.vpnService.state==.connected{
41-
ForEach(self.vpnService.data){ workspacein
54+
letvisibleData= viewAll? vpnService.data:Array(vpnService.data.prefix(defaultVisibleRows))
55+
ForEach(visibleData){ workspacein
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
}

‎DesktopTests/DesktopTests.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
import Testing
21
@testableimport Desktop
2+
import Testing
33

44
structDesktopTests{
5-
65
@Testfunc example()asyncthrows{
76
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
87
}
9-
108
}

‎DesktopUITests/DesktopUITests.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import XCTest
22

33
finalclassDesktopUITests:XCTestCase{
4-
54
overridefunc setUpWithError()throws{
65
// Put setup code here. This method is called before the invocation of each test method in the class.
76

‎DesktopUITests/DesktopUITestsLaunchTests.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import XCTest
22

33
finalclassDesktopUITestsLaunchTests:XCTestCase{
4-
54
overrideclassvarrunsForEachTargetApplicationUIConfiguration:Bool{
65
true
76
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp