Skip to content

Commit 65dc849

Browse files
committed
Merge branch 'feature/tweak-prompt-to-code' into develop
2 parents 6f4208c + a9077ef commit 65dc849

1 file changed

Lines changed: 124 additions & 101 deletions

File tree

Core/Sources/SuggestionWidget/SuggestionPanelContent/PromptToCodePanel.swift

Lines changed: 124 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -3,74 +3,73 @@ import SwiftUI
33

44
struct PromptToCodePanel: View {
55
@ObservedObject var provider: PromptToCodeProvider
6-
@Environment(\.colorScheme) var colorScheme
76

87
var body: some View {
98
VStack(spacing: 0) {
10-
CustomScrollView {
11-
VStack(spacing: 0) {
12-
if !provider.errorMessage.isEmpty {
13-
Text(provider.errorMessage)
14-
.multilineTextAlignment(.leading)
15-
.frame(maxWidth: .infinity, alignment: .leading)
16-
.foregroundColor(.white)
17-
.padding()
18-
.background(Color.red)
19-
}
20-
21-
if provider.code.isEmpty {
22-
Text(
23-
provider.isResponding
24-
? "Thinking..."
25-
: "Enter your requirement to generate code."
26-
)
27-
.foregroundColor(.secondary)
28-
.padding()
29-
.multilineTextAlignment(.center)
30-
.frame(maxWidth: .infinity)
31-
} else {
32-
CodeBlock(
33-
code: provider.code,
34-
language: provider.language,
35-
startLineIndex: provider.startLineIndex,
36-
colorScheme: colorScheme,
37-
firstLinePrecedingSpaceCount: provider.startLineColumn
38-
)
39-
.frame(maxWidth: .infinity)
9+
PromptToCodePanelContent(provider: provider)
10+
.overlay(alignment: .topTrailing) {
11+
if !provider.code.isEmpty {
12+
CopyButton {
13+
NSPasteboard.general.clearContents()
14+
NSPasteboard.general.setString(provider.code, forType: .string)
15+
}
16+
.padding(.trailing, 2)
17+
.padding(.top, 2)
4018
}
19+
}
20+
.overlay(alignment: .bottom) {
21+
HStack {
22+
if provider.isResponding {
23+
Button(action: {
24+
provider.stopResponding()
25+
}) {
26+
HStack(spacing: 4) {
27+
Image(systemName: "stop.fill")
28+
Text("Stop")
29+
}
30+
.padding(8)
31+
.background(
32+
.regularMaterial,
33+
in: RoundedRectangle(cornerRadius: 6, style: .continuous)
34+
)
35+
.overlay {
36+
RoundedRectangle(cornerRadius: 6, style: .continuous)
37+
.stroke(Color(nsColor: .separatorColor), lineWidth: 1)
38+
}
39+
}
40+
.buttonStyle(.plain)
41+
}
4142

42-
if !provider.description.isEmpty {
43-
Markdown(provider.description)
44-
.textSelection(.enabled)
45-
.markdownTheme(.gitHub.text {
46-
BackgroundColor(Color.clear)
47-
})
48-
.padding()
49-
.frame(maxWidth: .infinity)
50-
}
43+
let isRespondingButCodeIsReady = provider.isResponding
44+
&& !provider.code.isEmpty
45+
&& !provider.description.isEmpty
5146

52-
Spacer(minLength: 50)
53-
}
54-
}
55-
.overlay(alignment: .topTrailing) {
56-
if !provider.code.isEmpty {
57-
CopyButton {
58-
NSPasteboard.general.clearContents()
59-
NSPasteboard.general.setString(provider.code, forType: .string)
60-
}
61-
.padding(.trailing, 2)
62-
.padding(.top, 2)
63-
}
64-
}
65-
.overlay(alignment: .bottom) {
66-
Group {
67-
if provider.isResponding {
68-
Button(action: {
69-
provider.stopResponding()
70-
}) {
71-
HStack(spacing: 4) {
72-
Image(systemName: "stop.fill")
73-
Text("Stop Responding")
47+
if !provider.isResponding || isRespondingButCodeIsReady {
48+
HStack {
49+
Toggle(
50+
"Continuous Mode",
51+
isOn: .init(
52+
get: { provider.isContinuous },
53+
set: { _ in provider.toggleContinuous() }
54+
)
55+
)
56+
.toggleStyle(.checkbox)
57+
58+
Button(action: {
59+
provider.cancel()
60+
}) {
61+
Text("Cancel")
62+
}.buttonStyle(CommandButtonStyle(color: .gray))
63+
64+
if !provider.code.isEmpty {
65+
Button(action: {
66+
provider.acceptSuggestion()
67+
}) {
68+
Text("Accept(⌘ + ⏎)")
69+
}
70+
.buttonStyle(CommandButtonStyle(color: .indigo))
71+
.keyboardShortcut(KeyEquivalent.return, modifiers: [.command])
72+
}
7473
}
7574
.padding(8)
7675
.background(
@@ -82,47 +81,9 @@ struct PromptToCodePanel: View {
8281
.stroke(Color(nsColor: .separatorColor), lineWidth: 1)
8382
}
8483
}
85-
.buttonStyle(.plain)
86-
} else {
87-
HStack {
88-
Toggle(
89-
"Continuous Mode",
90-
isOn: .init(
91-
get: { provider.isContinuous },
92-
set: { _ in provider.toggleContinuous() }
93-
)
94-
)
95-
.toggleStyle(.checkbox)
96-
97-
Button(action: {
98-
provider.cancel()
99-
}) {
100-
Text("Cancel")
101-
}.buttonStyle(CommandButtonStyle(color: .gray))
102-
103-
if !provider.code.isEmpty {
104-
Button(action: {
105-
provider.acceptSuggestion()
106-
}) {
107-
Text("Accept(⌘ + ⏎)")
108-
}
109-
.buttonStyle(CommandButtonStyle(color: .indigo))
110-
.keyboardShortcut(KeyEquivalent.return, modifiers: [.command])
111-
}
112-
}
113-
.padding(8)
114-
.background(
115-
.regularMaterial,
116-
in: RoundedRectangle(cornerRadius: 6, style: .continuous)
117-
)
118-
.overlay {
119-
RoundedRectangle(cornerRadius: 6, style: .continuous)
120-
.stroke(Color(nsColor: .separatorColor), lineWidth: 1)
121-
}
12284
}
85+
.padding(.bottom, 8)
12386
}
124-
.padding(.bottom, 8)
125-
}
12687

12788
PromptToCodePanelToolbar(provider: provider)
12889
}
@@ -131,6 +92,68 @@ struct PromptToCodePanel: View {
13192
}
13293
}
13394

95+
struct PromptToCodePanelContent: View {
96+
@ObservedObject var provider: PromptToCodeProvider
97+
@Environment(\.colorScheme) var colorScheme
98+
99+
var body: some View {
100+
CustomScrollView {
101+
VStack(spacing: 0) {
102+
Spacer(minLength: 60)
103+
104+
if !provider.errorMessage.isEmpty {
105+
Text(provider.errorMessage)
106+
.multilineTextAlignment(.leading)
107+
.foregroundColor(.white)
108+
.padding(.horizontal, 8)
109+
.padding(.vertical, 2)
110+
.background(
111+
Color.red,
112+
in: RoundedRectangle(cornerRadius: 16, style: .continuous)
113+
)
114+
.scaleEffect(x: -1, y: -1, anchor: .center)
115+
}
116+
117+
if !provider.description.isEmpty {
118+
Markdown(provider.description)
119+
.textSelection(.enabled)
120+
.markdownTheme(.gitHub.text {
121+
BackgroundColor(Color.clear)
122+
})
123+
.padding()
124+
.frame(maxWidth: .infinity)
125+
.scaleEffect(x: -1, y: -1, anchor: .center)
126+
}
127+
128+
if provider.code.isEmpty {
129+
Text(
130+
provider.isResponding
131+
? "Thinking..."
132+
: "Enter your requirement to generate code."
133+
)
134+
.foregroundColor(.secondary)
135+
.padding()
136+
.multilineTextAlignment(.center)
137+
.frame(maxWidth: .infinity)
138+
.scaleEffect(x: -1, y: -1, anchor: .center)
139+
} else {
140+
CodeBlock(
141+
code: provider.code,
142+
language: provider.language,
143+
startLineIndex: provider.startLineIndex,
144+
colorScheme: colorScheme,
145+
firstLinePrecedingSpaceCount: provider.startLineColumn
146+
)
147+
.frame(maxWidth: .infinity)
148+
.scaleEffect(x: -1, y: -1, anchor: .center)
149+
}
150+
}
151+
.scaleEffect(x: -1, y: 1, anchor: .center)
152+
}
153+
.scaleEffect(x: 1, y: -1, anchor: .center)
154+
}
155+
}
156+
134157
struct PromptToCodePanelToolbar: View {
135158
@ObservedObject var provider: PromptToCodeProvider
136159
@FocusState var isInputAreaFocused: Bool

0 commit comments

Comments
 (0)