Skip to content

Commit 840df63

Browse files
committed
extract
1 parent e9ddfbc commit 840df63

File tree

3 files changed

+96
-94
lines changed

3 files changed

+96
-94
lines changed

Desktop/AgentRow.swift

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import SwiftUI
2+
3+
struct AgentRow: Identifiable {
4+
let id: UUID
5+
let name: String
6+
let status: Color
7+
let copyableDNS: String
8+
}
9+
10+
struct AgentRowView: View {
11+
let workspace: AgentRow
12+
@State private var nameIsSelected: Bool = false
13+
@State private var copyIsSelected: Bool = false
14+
15+
private var fmtWsName: AttributedString {
16+
var formattedName = AttributedString(workspace.name)
17+
formattedName.foregroundColor = .primary
18+
var coderPart = AttributedString(".coder")
19+
coderPart.foregroundColor = .gray
20+
formattedName.append(coderPart)
21+
return formattedName
22+
}
23+
24+
var body: some View {
25+
HStack(spacing: 0) {
26+
Button {
27+
// TODO: Action
28+
} label: {
29+
HStack(spacing: 10) {
30+
ZStack {
31+
Circle()
32+
.fill(workspace.status.opacity(0.4))
33+
.frame(width: 12, height: 12)
34+
Circle()
35+
.fill(workspace.status.opacity(1.0))
36+
.frame(width: 7, height: 7)
37+
}
38+
Text(fmtWsName).lineLimit(1).truncationMode(.tail)
39+
Spacer()
40+
}.padding(.horizontal, 10)
41+
.frame(minHeight: 22)
42+
.frame(maxWidth: .infinity, alignment: .leading)
43+
.foregroundStyle(nameIsSelected ? Color.white : .primary)
44+
.background(nameIsSelected ? Color.accentColor.opacity(0.8) : .clear)
45+
.clipShape(.rect(cornerRadius: 4))
46+
.onHover { hovering in nameIsSelected = hovering }
47+
Spacer()
48+
}.buttonStyle(.plain)
49+
Button {
50+
// TODO: Proper clipboard abstraction
51+
NSPasteboard.general.setString(workspace.copyableDNS, forType: .string)
52+
} label: {
53+
Image(systemName: "doc.on.doc")
54+
.symbolVariant(.fill)
55+
.padding(3)
56+
}.foregroundStyle(copyIsSelected ? Color.white : .primary)
57+
.imageScale(.small)
58+
.background(copyIsSelected ? Color.accentColor.opacity(0.8) : .clear)
59+
.clipShape(.rect(cornerRadius: 4))
60+
.onHover { hovering in copyIsSelected = hovering }
61+
.buttonStyle(.plain)
62+
.padding(.trailing, 5)
63+
}
64+
}
65+
}

Desktop/ButtonRow.swift

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import SwiftUI
2+
3+
struct ButtonRowView<Label: View>: View {
4+
@State private var isSelected: Bool = false
5+
@ViewBuilder var label: () -> Label
6+
var action: () -> Void
7+
8+
var body: some View {
9+
Button {
10+
action()
11+
} label: {
12+
HStack(spacing: 0) {
13+
label()
14+
Spacer()
15+
}
16+
.padding(.horizontal, 10)
17+
.frame(minHeight: 22)
18+
.frame(maxWidth: .infinity, alignment: .leading)
19+
.foregroundStyle(isSelected ? Color.white : .primary)
20+
.background(isSelected ? Color.accentColor.opacity(0.8) : .clear)
21+
.clipShape(.rect(cornerRadius: 4))
22+
.onHover { hovering in isSelected = hovering }
23+
}.buttonStyle(.plain)
24+
}
25+
}

Desktop/VPNMenu.swift

+6-94
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import SwiftUI
22

3-
struct VPNMenu<Conn: CoderVPN>: View {
4-
@ObservedObject var vpnService: Conn
3+
struct VPNMenu<VPN: CoderVPN>: View {
4+
@ObservedObject var vpnService: VPN
55

66
var body: some View {
77
// Main stack
@@ -45,24 +45,24 @@ struct VPNMenu<Conn: CoderVPN>: View {
4545
// Trailing stack
4646
VStack(alignment: .leading, spacing: 3) {
4747
Divider().padding([.horizontal], 10).padding(.vertical, 4)
48-
RowButtonView {
48+
ButtonRowView {
4949
Text("Create workspace")
5050
EmptyView()
5151
} action: {
5252
// TODO
5353
}
5454
Divider().padding([.horizontal], 10).padding(.vertical, 4)
55-
RowButtonView {
55+
ButtonRowView {
5656
Text("About")
5757
} action: {
5858
// TODO
5959
}
60-
RowButtonView {
60+
ButtonRowView {
6161
Text("Preferences")
6262
} action: {
6363
// TODO
6464
}
65-
RowButtonView {
65+
ButtonRowView {
6666
Text("Sign out")
6767
} action: {
6868
// TODO
@@ -72,94 +72,6 @@ struct VPNMenu<Conn: CoderVPN>: View {
7272
}
7373
}
7474

75-
struct AgentRow: Identifiable {
76-
let id: UUID
77-
let name: String
78-
let status: Color
79-
let copyableDNS: String
80-
}
81-
82-
struct AgentRowView: View {
83-
let workspace: AgentRow
84-
@State private var nameIsSelected: Bool = false
85-
@State private var copyIsSelected: Bool = false
86-
87-
private var fmtWsName: AttributedString {
88-
var formattedName = AttributedString(workspace.name)
89-
formattedName.foregroundColor = .primary
90-
var coderPart = AttributedString(".coder")
91-
coderPart.foregroundColor = .gray
92-
formattedName.append(coderPart)
93-
return formattedName
94-
}
95-
96-
var body: some View {
97-
HStack(spacing: 0) {
98-
Button {
99-
// TODO: Action
100-
} label: {
101-
HStack(spacing: 10) {
102-
ZStack {
103-
Circle()
104-
.fill(workspace.status.opacity(0.4))
105-
.frame(width: 12, height: 12)
106-
Circle()
107-
.fill(workspace.status.opacity(1.0))
108-
.frame(width: 7, height: 7)
109-
}
110-
Text(fmtWsName).lineLimit(1).truncationMode(.tail)
111-
Spacer()
112-
}.padding(.horizontal, 10)
113-
.frame(minHeight: 22)
114-
.frame(maxWidth: .infinity, alignment: .leading)
115-
.foregroundStyle(nameIsSelected ? Color.white : .primary)
116-
.background(nameIsSelected ? Color.accentColor.opacity(0.8) : .clear)
117-
.clipShape(.rect(cornerRadius: 4))
118-
.onHover { hovering in nameIsSelected = hovering }
119-
Spacer()
120-
}.buttonStyle(.plain)
121-
Button {
122-
// TODO: Proper clipboard abstraction
123-
NSPasteboard.general.setString(workspace.copyableDNS, forType: .string)
124-
} label: {
125-
Image(systemName: "doc.on.doc")
126-
.symbolVariant(.fill)
127-
.padding(3)
128-
}.foregroundStyle(copyIsSelected ? Color.white : .primary)
129-
.imageScale(.small)
130-
.background(copyIsSelected ? Color.accentColor.opacity(0.8) : .clear)
131-
.clipShape(.rect(cornerRadius: 4))
132-
.onHover { hovering in copyIsSelected = hovering }
133-
.buttonStyle(.plain)
134-
.padding(.trailing, 5)
135-
}
136-
}
137-
}
138-
139-
struct RowButtonView<Label: View>: View {
140-
@State private var isSelected: Bool = false
141-
@ViewBuilder var label: () -> Label
142-
var action: () -> Void
143-
144-
var body: some View {
145-
Button {
146-
action()
147-
} label: {
148-
HStack(spacing: 0) {
149-
label()
150-
Spacer()
151-
}
152-
.padding(.horizontal, 10)
153-
.frame(minHeight: 22)
154-
.frame(maxWidth: .infinity, alignment: .leading)
155-
.foregroundStyle(isSelected ? Color.white : .primary)
156-
.background(isSelected ? Color.accentColor.opacity(0.8) : .clear)
157-
.clipShape(.rect(cornerRadius: 4))
158-
.onHover { hovering in isSelected = hovering }
159-
}.buttonStyle(.plain)
160-
}
161-
}
162-
16375
#Preview {
16476
VPNMenu(vpnService: PreviewVPN()).frame(width: 256)
16577
}

0 commit comments

Comments
 (0)