Skip to content

Commit 966f654

Browse files
committed
Add SubSection
1 parent f4130c9 commit 966f654

File tree

2 files changed

+123
-34
lines changed

2 files changed

+123
-34
lines changed

Core/Sources/HostApp/FeatureSettings/ChatSettingsView.swift

Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -244,25 +244,27 @@ struct ChatSettingsView: View {
244244
@StateObject var settings = Settings()
245245

246246
var body: some View {
247+
SettingsDivider("Scopes")
248+
247249
VStack {
248-
Scope(
250+
SubSection(
249251
title: Text("File Scope"),
250252
description: "Enable the bot to read the metadata of the editing file."
251253
) {
252254
Form {
253255
Toggle(isOn: $settings.enableFileScopeByDefaultInChatContext) {
254-
Text("Enable @file scope by default in chat context.")
256+
Text("Enable by default")
255257
}
256258
}
257259
}
258260

259-
Scope(
261+
SubSection(
260262
title: Text("Code Scope"),
261263
description: "Enable the bot to read the code and metadata in the editing file."
262264
) {
263265
Form {
264266
Toggle(isOn: $settings.enableCodeScopeByDefaultInChatContext) {
265-
Text("Enable @code scope by default in chat context.")
267+
Text("Enable by default")
266268
}
267269

268270
HStack {
@@ -282,16 +284,16 @@ struct ChatSettingsView: View {
282284

283285
#if canImport(ProHostApp)
284286

285-
Scope(
286-
title: WithFeatureEnabled(\.projectScopeInChat) {
287+
SubSection(
288+
title: WithFeatureEnabled(\.projectScopeInChat, alignment: .trailing) {
287289
Text("Sense Scope (Experimental)")
288290
},
289291
description: "Experimental. Enable the bot to read the relevant code of the editing file in the project, third party packages and the SDK."
290292
) {
291293
WithFeatureEnabled(\.projectScopeInChat, alignment: .hidden) {
292294
Form {
293295
Toggle(isOn: $settings.enableSenseScopeByDefaultInChatContext) {
294-
Text("Enable @sense scope by default in chat context.")
296+
Text("Enable by default")
295297
}
296298

297299
Picker(
@@ -321,16 +323,16 @@ struct ChatSettingsView: View {
321323
}
322324
}
323325

324-
Scope(
325-
title: WithFeatureEnabled(\.projectScopeInChat) {
326+
SubSection(
327+
title: WithFeatureEnabled(\.projectScopeInChat, alignment: .trailing) {
326328
Text("Project Scope (Experimental)")
327329
},
328-
description: "Experimental. Enable the bot to search code symbols in the project, third party packages and the SDK."
330+
description: "Experimental. Enable the bot to search code symbols in the project, third party packages and the SDK."
329331
) {
330332
WithFeatureEnabled(\.projectScopeInChat, alignment: .hidden) {
331333
Form {
332334
Toggle(isOn: $settings.enableProjectScopeByDefaultInChatContext) {
333-
Text("Enable @project scope by default in chat context.")
335+
Text("Enable by default")
334336
}
335337

336338
Picker(
@@ -362,7 +364,7 @@ struct ChatSettingsView: View {
362364

363365
#endif
364366

365-
Scope(
367+
SubSection(
366368
title: Text("Web Scope"),
367369
description: "Allow the bot to search on Bing or read a web page."
368370
) {
@@ -398,28 +400,6 @@ struct ChatSettingsView: View {
398400
}
399401
}
400402
}
401-
402-
struct Scope<Title: View, Content: View>: View {
403-
let title: Title
404-
let description: String
405-
let content: () -> Content
406-
407-
var body: some View {
408-
SettingsDivider(title)
409-
VStack {
410-
Text(description)
411-
.multilineTextAlignment(.center)
412-
.foregroundStyle(.secondary)
413-
.frame(maxWidth: .infinity)
414-
.padding(8)
415-
.background {
416-
RoundedRectangle(cornerRadius: 8)
417-
.fill(Color.secondary.opacity(0.1))
418-
}
419-
content()
420-
}
421-
}
422-
}
423403
}
424404
}
425405

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import SwiftUI
2+
3+
struct SubSection<Title: View, Content: View>: View {
4+
let title: Title
5+
let description: String
6+
@ViewBuilder let content: () -> Content
7+
8+
init(title: Title, description: String = "", @ViewBuilder content: @escaping () -> Content) {
9+
self.title = title
10+
self.description = description
11+
self.content = content
12+
}
13+
14+
var body: some View {
15+
VStack(alignment: .leading) {
16+
if !(title is EmptyView && description.isEmpty) {
17+
VStack(alignment: .leading, spacing: 8) {
18+
title
19+
20+
if !description.isEmpty {
21+
Text(description)
22+
.multilineTextAlignment(.leading)
23+
.foregroundStyle(.secondary)
24+
}
25+
}
26+
.frame(maxWidth: .infinity, alignment: .leading)
27+
}
28+
29+
if !(title is EmptyView && description.isEmpty) {
30+
Divider()
31+
}
32+
33+
content()
34+
}
35+
.padding()
36+
.background {
37+
RoundedRectangle(cornerRadius: 8)
38+
.fill(Color.secondary.opacity(0.1))
39+
}
40+
.overlay {
41+
RoundedRectangle(cornerRadius: 8)
42+
.strokeBorder(Color.secondary.opacity(0.2))
43+
}
44+
}
45+
}
46+
47+
extension SubSection where Title == EmptyView {
48+
init(description: String = "", @ViewBuilder content: @escaping () -> Content) {
49+
self.init(title: EmptyView(), description: description, content: content)
50+
}
51+
}
52+
53+
#Preview("Sub Section Default Style") {
54+
SubSection(title: Text("Title"), description: "Description") {
55+
Toggle(isOn: .constant(true), label: {
56+
Text("Label")
57+
})
58+
59+
Toggle(isOn: .constant(true), label: {
60+
Text("Label")
61+
})
62+
63+
Picker("Label", selection: .constant(0)) {
64+
Text("Label").tag(0)
65+
Text("Label").tag(1)
66+
Text("Label").tag(2)
67+
}
68+
}
69+
.padding()
70+
}
71+
72+
#Preview("Sub Section No Title") {
73+
SubSection(description: "Description") {
74+
Toggle(isOn: .constant(true), label: {
75+
Text("Label")
76+
})
77+
78+
Toggle(isOn: .constant(true), label: {
79+
Text("Label")
80+
})
81+
82+
Picker("Label", selection: .constant(0)) {
83+
Text("Label").tag(0)
84+
Text("Label").tag(1)
85+
Text("Label").tag(2)
86+
}
87+
}
88+
.padding()
89+
}
90+
91+
#Preview("Sub Section No Title or Description") {
92+
SubSection {
93+
Toggle(isOn: .constant(true), label: {
94+
Text("Label")
95+
})
96+
97+
Toggle(isOn: .constant(true), label: {
98+
Text("Label")
99+
})
100+
101+
Picker("Label", selection: .constant(0)) {
102+
Text("Label").tag(0)
103+
Text("Label").tag(1)
104+
Text("Label").tag(2)
105+
}
106+
}
107+
.padding()
108+
}
109+

0 commit comments

Comments
 (0)